Spice plot widget: more accurate rendering
Patch modifies the way graphs are displayed: instead of drawing one point for each X coordinate, there is a line segment joining min and max values for continuous graphs and all unique points are displayed for discrete graphs. Fixes: lp:1674143 * https://bugs.launchpad.net/kicad/+bug/1674143
This commit is contained in:
parent
70c1de3275
commit
416e64a334
|
@ -42,6 +42,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdio> // used only for debug
|
#include <cstdio> // used only for debug
|
||||||
#include <ctime> // used for representation of x axes involving date
|
#include <ctime> // used for representation of x axes involving date
|
||||||
|
#include <set>
|
||||||
|
|
||||||
// Memory leak debugging
|
// Memory leak debugging
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
|
@ -642,103 +643,128 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
|
||||||
|
|
||||||
dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
|
dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
|
||||||
|
|
||||||
wxCoord ix = std::numeric_limits<wxCoord>::min(), iy = 0;
|
|
||||||
|
|
||||||
if( !m_continuous )
|
if( !m_continuous )
|
||||||
{
|
{
|
||||||
// for some reason DrawPoint does not use the current pen,
|
bool first = true;
|
||||||
// so we use DrawLine for fat pens
|
wxCoord ix;
|
||||||
if( m_pen.GetWidth() <= 1 )
|
std::set<wxCoord> ys;
|
||||||
|
|
||||||
|
while( GetNextXY( x, y ) )
|
||||||
{
|
{
|
||||||
while( GetNextXY( x, y ) )
|
double px = m_scaleX->TransformToPlot( x );
|
||||||
|
double py = m_scaleY->TransformToPlot( y );
|
||||||
|
wxCoord newX = w.x2p( px );
|
||||||
|
|
||||||
|
if( first )
|
||||||
{
|
{
|
||||||
double px = m_scaleX->TransformToPlot( x );
|
ix = newX;
|
||||||
double py = m_scaleY->TransformToPlot( y );
|
first = false;
|
||||||
wxCoord newX = w.x2p( px );
|
}
|
||||||
|
|
||||||
if( newX == ix ) // continue until a new X coordinate is reached
|
if( newX == ix ) // continue until a new X coordinate is reached
|
||||||
continue;
|
{
|
||||||
|
// collect all unique points
|
||||||
ix = newX;
|
ys.insert( w.y2p( py ) );
|
||||||
iy = w.y2p( py );
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( auto& iy: ys )
|
||||||
|
{
|
||||||
if( m_drawOutsideMargins
|
if( m_drawOutsideMargins
|
||||||
|| ( (ix >= startPx) && (ix <= endPx) && (iy >= minYpx)
|
|| ( (ix >= startPx) && (ix <= endPx) && (iy >= minYpx)
|
||||||
&& (iy <= maxYpx) ) )
|
&& (iy <= maxYpx) ) )
|
||||||
{
|
{
|
||||||
dc.DrawPoint( ix, iy );
|
// for some reason DrawPoint does not use the current pen,
|
||||||
|
// so we use DrawLine for fat pens
|
||||||
|
if( m_pen.GetWidth() <= 1 )
|
||||||
|
{
|
||||||
|
dc.DrawPoint( ix, iy );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc.DrawLine( ix, iy, ix, iy );
|
||||||
|
}
|
||||||
|
|
||||||
UpdateViewBoundary( ix, iy );
|
UpdateViewBoundary( ix, iy );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while( GetNextXY( x, y ) )
|
|
||||||
{
|
|
||||||
double px = m_scaleX->TransformToPlot( x );
|
|
||||||
double py = m_scaleY->TransformToPlot( y );
|
|
||||||
|
|
||||||
wxCoord newX = w.x2p( px );
|
ys.clear();
|
||||||
|
ix = newX;
|
||||||
if( newX == ix ) // continue until a new X coordinate is reached
|
ys.insert( w.y2p( py ) );
|
||||||
continue;
|
|
||||||
|
|
||||||
ix = newX;
|
|
||||||
iy = w.y2p( py );
|
|
||||||
|
|
||||||
if( m_drawOutsideMargins
|
|
||||||
|| ( (ix >= startPx) && (ix <= endPx) && (iy >= minYpx)
|
|
||||||
&& (iy <= maxYpx) ) )
|
|
||||||
{
|
|
||||||
dc.DrawLine( ix, iy, ix, iy );
|
|
||||||
UpdateViewBoundary( ix, iy );
|
|
||||||
}
|
|
||||||
|
|
||||||
// dc.DrawLine(cx, cy, cx, cy);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int n = 0;
|
wxCoord x0, y0;
|
||||||
// Old code
|
bool first = true;
|
||||||
wxCoord x0 = 0, c0 = 0;
|
|
||||||
bool first = true;
|
wxCoord minY, maxY;
|
||||||
|
bool minFirst = true;
|
||||||
|
|
||||||
while( GetNextXY( x, y ) )
|
while( GetNextXY( x, y ) )
|
||||||
{
|
{
|
||||||
double px = m_scaleX->TransformToPlot( x );
|
double px = m_scaleX->TransformToPlot( x );
|
||||||
double py = m_scaleY->TransformToPlot( y );
|
double py = m_scaleY->TransformToPlot( y );
|
||||||
|
|
||||||
if( py >= 0.0 && py <= 1.0 )
|
|
||||||
n++;
|
|
||||||
|
|
||||||
wxCoord x1 = w.x2p( px );
|
wxCoord x1 = w.x2p( px );
|
||||||
wxCoord c1 = w.y2p( py );
|
wxCoord y1 = w.y2p( py );
|
||||||
|
|
||||||
if( first )
|
if( first )
|
||||||
{
|
{
|
||||||
first = false;
|
first = false;
|
||||||
x0 = x1; c0 = c1;
|
x0 = x1; y0 = y1;
|
||||||
}
|
minY = y1;
|
||||||
else if( x0 == x1 ) // continue until a new X coordinate is reached
|
maxY = y1;
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( x1 >= startPx ) && ( x0 <= endPx ) )
|
if( x0 == x1 ) // continue until a new X coordinate is reached
|
||||||
{
|
{
|
||||||
bool outDown = ( c0 > maxYpx ) && ( c1 > maxYpx );
|
// determine min and max, so they can also be marked on the plot
|
||||||
bool outUp = ( c0 < minYpx ) && ( c1 < minYpx );
|
if( y1 > maxY )
|
||||||
|
{
|
||||||
|
maxY = y1;
|
||||||
|
minFirst = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( y1 < minY )
|
||||||
|
{
|
||||||
|
minY = y1;
|
||||||
|
minFirst = false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCoord firstY = minFirst ? minY : maxY;
|
||||||
|
wxCoord secondY = minFirst ? maxY : minY;
|
||||||
|
|
||||||
|
if( ( x0 >= startPx ) && ( x0 <= endPx ) )
|
||||||
|
{
|
||||||
|
bool outDown = ( y0 > maxYpx ) && ( firstY > maxYpx );
|
||||||
|
bool outUp = ( y0 < minYpx ) && ( firstY < minYpx );
|
||||||
|
|
||||||
if( !outUp && !outDown )
|
if( !outUp && !outDown )
|
||||||
{
|
{
|
||||||
dc.DrawLine( x0, c0, x1, c1 );
|
dc.DrawLine( x0, y0, x0, firstY );
|
||||||
// UpdateViewBoundary(x1, c1);
|
// UpdateViewBoundary(x1, firstY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x0 = x1; c0 = c1;
|
bool outDown = ( firstY > maxYpx ) && ( secondY > maxYpx );
|
||||||
|
bool outUp = ( firstY < minYpx ) && ( secondY < minYpx );
|
||||||
|
bool outLeft = ( x1 < startPx ) && ( x0 < startPx );
|
||||||
|
bool outRight = ( x1 > endPx ) && ( x0 > endPx );
|
||||||
|
if( !( outUp || outDown || outLeft || outRight ) )
|
||||||
|
{
|
||||||
|
dc.DrawLine( x0, firstY, x1, secondY );
|
||||||
|
// UpdateViewBoundary(x1, secondY);
|
||||||
|
}
|
||||||
|
|
||||||
|
x0 = x1;
|
||||||
|
y0 = secondY;
|
||||||
|
minY = y1;
|
||||||
|
maxY = y1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue