Simulator: optimize a plot function, to support large amount of points.

Redundant points are not plotted.

Fixes #4737
https://gitlab.com/kicad/code/kicad/issues/4737
This commit is contained in:
jean-pierre charras 2020-07-27 10:47:52 +02:00
parent 8324cb30b7
commit 0103164571
1 changed files with 41 additions and 8 deletions

View File

@ -696,9 +696,20 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
} }
else else
{ {
wxPoint* points = new wxPoint[GetCount()]; int count = 0;
int count = 0; int x0=0; // X position of merged current vertical line
int ymin0=0; // y min coord of merged current vertical line
int ymax0=0; // y max coord of merged current vertical line
int dupx0 = 0; // count of currently merged vertical lines
wxPoint line_start; // starting point of the current line to draw
// Note: we do not use dc.DrawLines(), because at least on Windows
// dc.DrawLine() is faster, and dc.DrawLines() can hang for a lot
// (> 10000 points) (can happens when a lot of points is calculated)
// To avoid long draw time (and perhaps hanging) one plot only not redundant lines.
// To avoid artifacts when skipping points to the same x coordinate, for each
// group of points at a give, x coordinate we also draw a vertical line at this coord,
// from the ymin to the ymax vertical coordinates of skipped points
while( GetNextXY( x, y ) ) while( GetNextXY( x, y ) )
{ {
double px = m_scaleX->TransformToPlot( x ); double px = m_scaleX->TransformToPlot( x );
@ -707,13 +718,35 @@ void mpFXY::Plot( wxDC& dc, mpWindow& w )
wxCoord x1 = w.x2p( px ); wxCoord x1 = w.x2p( px );
wxCoord y1 = w.y2p( py ); wxCoord y1 = w.y2p( py );
points[count++] = wxPoint( x1, y1 ); // Store only points on the drawing area, to speed up the drawing time
if( x1 >= startPx && x1 <= endPx )
{
if( !count || line_start.x != x1 )
{
if( dupx0 > 1 ) // Vertical points are merged,
// draw the pending vertical line
dc.DrawLine( x0, ymin0, x0, ymax0 );
x0 = x1;
ymin0 = ymax0 = y1;
dupx0 = 0;
if( count )
dc.DrawLine( line_start, wxPoint( x1, y1 ) );
line_start.x = x1;
line_start.y = y1;
count++;
}
else
{
// "Merge" points on a vertical line at x0:
ymin0 = std::min( ymin0, y1 );
ymax0 = std::max( ymax0, y1 );
dupx0++;
}
}
} }
if( count > 0 )
dc.DrawLines( count, points );
delete[] points;
} }
if( !m_name.IsEmpty() && m_showName ) if( !m_name.IsEmpty() && m_showName )