29#include "wx/dcclient.h"
35#include <wx/graphics.h>
49#define mpLEGEND_MARGIN 5
50#define mpLEGEND_LINEWIDTH 10
53#define mpSCROLL_NUM_PIXELS_PER_LINE 10
62IMPLEMENT_ABSTRACT_CLASS(
mpLayer, wxObject )
67 SetPen( (wxPen&) *wxBLACK_PEN );
68 SetFont( (wxFont&) *wxNORMAL_FONT );
71 m_drawOutsideMargins =
false;
78 wxBitmap
square( side, side, -1 );
79 wxColour filler =
m_pen.GetColour();
80 wxBrush brush( filler, wxBRUSHSTYLE_SOLID );
84 dc.SetBackground( brush );
86 dc.SelectObject( wxNullBitmap );
98 m_dim = wxRect( 0, 0, 1, 1 );
99 m_brush = *wxTRANSPARENT_BRUSH;
100 m_reference.x = 0; m_reference.y = 0;
131 return m_dim.Contains( point );
192 return m_dim.GetPosition();
198 return m_dim.GetSize();
221 if( event.GetEventType() == wxEVT_MOTION )
266 dc.GetTextExtent(
m_content, &textX, &textY );
268 if(
m_dim.width < textX + 10 )
269 m_dim.width = textX + 10;
271 if(
m_dim.height < textY + 10 )
272 m_dim.height = textY + 10;
349 dc.GetTextExtent( label, &tmpX, &tmpY );
350 textX = ( textX > tmpX + baseWidth ) ? textX : tmpX + baseWidth +
mpLEGEND_MARGIN;
362 m_dim.height = textY;
373 dc.GetTextExtent( label, &tmpX, &tmpY );
421 if(
m_pen.GetWidth() <= 1 )
423 for( wxCoord i = startPx; i < endPx; ++i )
429 dc.DrawPoint( i, iy );
434 for( wxCoord i = startPx; i < endPx; ++i )
440 dc.DrawLine( i, iy, i, iy );
452 dc.GetTextExtent(
m_name, &tx, &ty );
498 if(
m_pen.GetWidth() <= 1 )
500 for( i = minYpx; i < maxYpx; ++i )
505 dc.DrawPoint( ix, i );
510 for( i = 0; i< w.
GetScrY(); ++i )
515 dc.DrawLine( ix, i, ix, i );
528 dc.GetTextExtent(
m_name, &tx, &ty );
555 maxDrawX = minDrawX = maxDrawY = minDrawY = 0;
577 wxCHECK_RET(
m_scaleX, wxS(
"X scale was not set" ) );
579 wxCHECK_RET(
m_scaleY, wxS(
"Y scale was not set" ) );
590 if( endPx <= startPx || minYpx >= maxYpx )
606 dc.SetClippingRegion( startPx, minYpx, endPx - startPx + 1, maxYpx - minYpx + 1 );
612 std::set<wxCoord> ys;
618 wxCoord newX = w.
x2p( px );
629 ys.insert( w.
y2p( py ) );
636 || ( (ix >= startPx) && (ix <= endPx) && (iy >= minYpx) && (iy <= maxYpx) ) )
640 if(
m_pen.GetWidth() <= 1 )
641 dc.DrawPoint( ix, iy );
643 dc.DrawLine( ix, iy, ix, iy );
651 ys.insert( w.
y2p( py ) );
664 std::vector<wxPoint>pointList;
665 pointList.reserve( endPx - startPx + 1 );
679 wxCoord x1 = w.
x2p( px );
680 wxCoord y1 = w.
y2p( py );
685 if( x1 >= startPx-1 && x1 <= endPx )
687 if( !count || line_start.x != x1 )
689 if( count && dupx0 > 1 && ymin0 != ymax0 )
694 dc.DrawLine( x0, ymin0, x0, ymax0 );
701 pointList.emplace_back( wxPoint( x1, y1 ) );
709 ymin0 = std::min( ymin0, y1 );
710 ymax0 = std::max( ymax0, y1 );
717 if( pointList.size() > 1 )
723 std::vector<wxPoint> drawPoints;
724 drawPoints.reserve( endPx - startPx + 1 );
726 drawPoints.push_back( pointList[0] );
728 for(
size_t ii = 1; ii < pointList.size()-1; ii++ )
732 if( drawPoints.back().y == pointList[ii].y &&
733 drawPoints.back().y == pointList[ii+1].y )
739 drawPoints.push_back( pointList[ii] );
744 if( drawPoints.back() != pointList.back() )
745 drawPoints.push_back( pointList.back() );
747 dc.DrawLines( drawPoints.size(), &drawPoints[0] );
756 dc.GetTextExtent(
m_name, &tx, &ty );
786 dc.DrawText(
m_name, tx, ty );
789 dc.DestroyClippingRegion();
819 for( wxCoord i = startPx; i < endPx; ++i )
828 c0 = (c0 <= maxYpx) ? ( (c0 >= minYpx) ? c0 : minYpx ) : maxYpx;
829 c1 = (c1 <= maxYpx) ? ( (c1 >= minYpx) ? c1 : minYpx ) : maxYpx;
832 dc.DrawLine( i, c0, i + 1, c1 );
842 dc.GetTextExtent(
m_name, &tx, &ty );
862#define mpLN10 2.3025850929940456840179914546844
866 double minV, maxV, minVvis, maxVvis;
876 double minErr = 1000000000000.0;
877 double bestStep = 1.0;
879 for(
int i = 10; i <= 20; i += 2 )
881 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
882 double base = pow( 10, floor( log10( curr_step ) ) );
883 double stepInt = floor( curr_step / base ) * base;
884 double err = fabs( curr_step - stepInt );
894 double v = floor( minVvis / bestStep ) * bestStep;
896 double zeroOffset = 100000000.0;
902 if( fabs( v ) < zeroOffset )
903 zeroOffset = fabs( v );
908 if( zeroOffset <= bestStep )
951 dc.GetTextExtent( s, &tx, &ty );
1007 double pymin = w.
p2y( minYpx );
1008 double pymax = w.
p2y( maxYpx );
1029 double y_slave0 = p0 /
m_scale;
1030 double y_slave1 = p1 /
m_scale;
1032 double dy_slave = (y_slave1 - y_slave0);
1033 double exponent = floor( log10( dy_slave ) );
1034 double base = dy_slave / pow( 10.0, exponent );
1036 double dy_scaled = ceil( 2.0 * base ) / 2.0 * pow( 10.0, exponent );
1038 double minvv, maxvv;
1042 minvv = floor( minvv / dy_scaled ) * dy_scaled;
1045 m_scale *= dy_slave / dy_scaled;
1075 double minV, maxV, minVvis, maxVvis;
1083 double minErr = 1000000000000.0;
1084 double bestStep = 1.0;
1086 for(
int i = 10; i <= 20; i += 2 )
1088 double curr_step = fabs( maxVvis - minVvis ) / (double) i;
1089 double base = pow( 10, floor( log10( curr_step ) ) );
1090 double stepInt = floor( curr_step / base ) * base;
1091 double err = fabs( curr_step - stepInt );
1101 double v = floor( minVvis / bestStep ) * bestStep;
1103 double zeroOffset = 100000000.0;
1105 const int iterLimit = 1000;
1108 while( v < maxVvis && i < iterLimit )
1112 if( fabs( v ) < zeroOffset )
1113 zeroOffset = fabs( v );
1121 if( i == iterLimit )
1126 if( zeroOffset <= bestStep )
1150 double pxmin = w.
p2x( startPx );
1151 double pxmax = w.
p2x( endPx );
1160 double minV, maxV, minVvis, maxVvis;
1166 double minDecade = pow( 10, floor( log10( minV ) ) );
1167 double maxDecade = pow( 10, ceil( log10( maxV ) ) );
1168 double visibleDecades = log( maxVvis / minVvis ) / log( 10 );
1175 if( minDecade == 0.0 )
1179 for( d = minDecade; d<=maxDecade; d *= 10.0 )
1183 for(
double dd = d; dd < d * 10; dd += d )
1185 if( visibleDecades < 2 )
1203 SetFont( (wxFont&) *wxSMALL_FONT );
1204 SetPen( (wxPen&) *wxGREY_PEN );
1239 const int extend = w.
GetScrX();
1288 if( (p >= startPx) && (p <= endPx) )
1293 dc.DrawLine( p, orgy, p, orgy - 4 );
1295 dc.DrawLine( p, orgy, p, orgy + 4 );
1299 m_pen.SetStyle( wxPENSTYLE_DOT );
1304 m_pen.SetStyle( wxPENSTYLE_DOT );
1306 dc.DrawLine( p, orgy + 4, p, minYpx );
1307 m_pen.SetStyle( wxPENSTYLE_SOLID );
1309 dc.DrawLine( p, orgy + 4, p, orgy - 4 );
1315 dc.DrawLine( p, orgy - 4, p, maxYpx );
1319 dc.DrawLine( p, minYpx, p, maxYpx );
1323 m_pen.SetStyle( wxPENSTYLE_SOLID );
1329 m_pen.SetStyle( wxPENSTYLE_SOLID );
1331 dc.DrawLine( startPx, minYpx, endPx, minYpx );
1332 dc.DrawLine( startPx, maxYpx, endPx, maxYpx );
1350 if( (p >= startPx) && (p <= endPx) )
1355 dc.GetTextExtent( s, &tx, &ty );
1359 dc.DrawText( s, p - tx / 2, orgy - 4 - ty );
1363 dc.DrawText( s, p - tx / 2, orgy + 4 );
1369 dc.GetTextExtent(
m_name, &tx, &ty );
1374 dc.DrawText(
m_name, extend - tx - 4, orgy - 8 - ty - labelH );
1379 dc.DrawText(
m_name, (endPx + startPx) / 2 - tx / 2, orgy + 6 + labelH );
1384 dc.DrawText(
m_name, extend - tx - 4, orgy - 4 - ty );
1391 dc.DrawText(
m_name, (endPx - startPx - tx) >> 1, orgy - 6 - ty - labelH );
1395 dc.DrawText(
m_name, extend - tx - 4, orgy + 4 );
1401 dc.DrawText(
m_name, extend - tx - 4, orgy + 6 + labelH );
1416 SetFont( (wxFont&) *wxSMALL_FONT );
1417 SetPen( (wxPen&) *wxGREY_PEN );
1421 m_masterScale =
nullptr;
1473 dc.DrawLine( orgx, minYpx, orgx, maxYpx );
1484 int labelHeight = 0;
1486 dc.GetTextExtent( s, &tx, &labelHeight );
1496 if( (p >= minYpx) && (p <= maxYpx) )
1502 dc.DrawLine( orgx, p, orgx + 4, p );
1506 dc.DrawLine( orgx - 4, p, orgx, p );
1511 dc.DrawLine( orgx - 4, p, orgx + 4, p );
1513 m_pen.SetStyle( wxPENSTYLE_DOT );
1516 dc.DrawLine( orgx - 4, p, endPx, p );
1518 m_pen.SetStyle( wxPENSTYLE_SOLID );
1536 if( (p >= minYpx) && (p <= maxYpx) )
1539 dc.GetTextExtent( s, &tx, &ty );
1542 dc.DrawText( s, orgx + 4, p - ty / 2 );
1544 dc.DrawText( s, orgx - 4 - tx, p - ty / 2 );
1551 dc.GetTextExtent(
m_name, &tx, &ty );
1556 dc.DrawText(
m_name, labelW + 8, 4 );
1564 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1570 dc.DrawText(
m_name, orgx + 4, 4 );
1581 dc.DrawText(
m_name, orgx - ( tx / 2 ), minYpx - ty - 4 );
1587 dc.DrawText(
m_name, orgx - 6 - tx - labelW, 4 );
1601IMPLEMENT_DYNAMIC_CLASS(
mpWindow, wxWindow )
1603BEGIN_EVENT_TABLE(
mpWindow, wxWindow )
1617#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
1633 m_lockaspect( false ),
1646 m_desiredXmin( 0.0 ),
1647 m_desiredXmax( 1.0 ),
1648 m_desiredYmin( 0.0 ),
1649 m_desiredYmax( 1.0 ),
1652 m_marginBottom( 0 ),
1656 m_buff_bmp(
nullptr ),
1657 m_enableDoubleBuffer( false ),
1658 m_enableMouseNavigation( true ),
1659 m_enableMouseWheelPan( false ),
1660 m_enableLimitedView( false ),
1661 m_enableScrollBars( false ),
1662 m_movingInfoLayer(
nullptr ),
1665 if( wxGraphicsContext *ctx = m_buff_dc.GetGraphicsContext() )
1667 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
1668 || !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
1670 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
1673 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
1682 : wxWindow( parent, id, pos, size,
flag, wxT(
"mathplot" ) )
1705 m_popmenu.Append(
mpID_FIT,
_(
"Fit on Screen" ),
_(
"Set plot view to show all items" ) );
1712 SetBackgroundColour( *wxWHITE );
1717 SetSizeHints( 128, 128 );
1720 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
1722 if( wxGraphicsContext* ctx =
m_buff_dc.GetGraphicsContext() )
1724 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
1725 || !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
1727 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
1730 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
1756#if wxCHECK_VERSION( 3, 1, 0 ) || defined( USE_OSX_MAGNIFY_EVENT )
1765 float zoom =
event.GetMagnification() + 1.0f;
1766 wxPoint pos( event.GetX(), event.GetY() );
1769 else if(
zoom < 1.0f )
1785 int change =
event.GetWheelRotation();
1786 const int axis =
event.GetWheelAxis();
1787 double changeUnitsX = change /
m_scaleX;
1788 double changeUnitsY = change /
m_scaleY;
1796 if( axis == wxMOUSE_WHEEL_HORIZONTAL || event.ShiftDown() )
1805 if( event.ControlDown() )
1818 wxPoint clickPt( event.GetX(), event.GetY() );
1820 if( event.GetWheelRotation() > 0 )
1840 wxCursor
cursor = wxCURSOR_MAGNIFIER;
1842 if( event.m_middleDown )
1857 bool updateRequired =
false;
1865 if( updateRequired )
1868 else if( event.m_leftDown )
1873 cursor = wxCURSOR_SIZING;
1875 cursor = wxCURSOR_SIZEWE;
1883 cursor = wxCURSOR_MAGNIFIER;
1885 wxClientDC dc(
this );
1888 dc.SetBrush( *wxTRANSPARENT_BRUSH );
1904 if( layer->IsInfo() && layer->IsVisible() )
1908 if( infoLayer->
Inside( event.GetPosition() ) )
1911 cursor = wxCURSOR_SIZING;
1913 cursor = wxCURSOR_SIZEWE;
1939 wxPoint pointClicked =
event.GetPosition();
1948 wxPoint release( event.GetX(), event.GetY() );
1960 if( release != press )
1977 wxCoord* printSizeX, wxCoord* printSizeY )
1984 double xExtra = fabs( xMax - xMin ) * 0.00;
1985 double yExtra = fabs( yMax - yMin ) * 0.03;
1992 if( printSizeX !=
nullptr && printSizeY !=
nullptr )
2033 if( printSizeX ==
nullptr || printSizeY ==
nullptr )
2042 double staticX =
p2x( staticXpixel );
2136 wxPoint c( centerPoint );
2138 if( c == wxDefaultPosition )
2153 double prior_layer_x =
p2x( c.x );
2154 double prior_layer_y =
p2y( c.y );
2158 double newScaleX =
m_scaleX * zoomFactor;
2159 double newScaleY =
m_scaleY * zoomFactor;
2193 wxPoint c( centerPoint );
2195 if( c == wxDefaultPosition )
2203 double prior_layer_x =
p2x( c.x );
2204 double prior_layer_y =
p2y( c.y );
2239 double p0x =
p2x( p0.x );
2240 double p0y =
p2y( p0.y );
2241 double p1x =
p2x( p1.x );
2242 double p1y =
p2y( p1.y );
2245 double zoom_x_min = p0x<p1x ? p0x : p1x;
2246 double zoom_x_max = p0x>p1x ? p0x : p1x;
2247 double zoom_y_min = p0y<p1y ? p0y : p1y;
2248 double zoom_y_max = p0y>p1y ? p0y : p1y;
2250 Fit( zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max );
2269 PopupMenu( &
m_popmenu, event.GetX(), event.GetY() );
2320 if( refreshDisplay )
2332 wxLayerList::iterator layIt;
2336 if( *layIt == layer )
2339 if( alsoDeleteObject )
2344 if( refreshDisplay )
2360 if( alsoDeleteObject )
2366 if( refreshDisplay )
2373 wxPaintDC dc(
this );
2402 if( wxGraphicsContext* ctx = trgDc->GetGraphicsContext() )
2404 if( !ctx->SetInterpolationQuality( wxINTERPOLATION_BEST )
2405 || !ctx->SetInterpolationQuality( wxINTERPOLATION_GOOD ) )
2407 ctx->SetInterpolationQuality( wxINTERPOLATION_FAST );
2410 ctx->SetAntialiasMode( wxANTIALIAS_DEFAULT );
2413 trgDc->SetPen( *wxTRANSPARENT_PEN );
2414 wxBrush brush( GetBackgroundColour() );
2415 trgDc->SetBrush( brush );
2421 wxLayerList::iterator li;
2424 (*li)->Plot( *trgDc, *
this );
2429 trgDc->SetPen( pen );
2430 trgDc->SetBrush( *wxTRANSPARENT_BRUSH );
2475 GetClientSize( &cx, &cy );
2484 if( (
m_posX + leftMargin) < minX )
2485 minX =
m_posX + leftMargin;
2488 int sizeX = (int) ( (maxX - minX) *
m_scaleX );
2489 int thumbX = (int) ( ( (
m_posX + leftMargin) - minX ) *
m_scaleX );
2499 if( (
m_posY - topMargin) > maxY )
2500 maxY =
m_posY - topMargin;
2504 int sizeY = (int) ( (maxY - minY) *
m_scaleY );
2505 int thumbY = (int) ( ( maxY - (
m_posY - topMargin) ) *
m_scaleY );
2517 if( orientation == wxVERTICAL )
2542 DoScrollCalc( event.GetPosition(), event.GetOrientation() );
2548 int scrollOrientation =
event.GetOrientation();
2550 int position = GetScrollPos( scrollOrientation );
2552 int thumbSize = GetScrollThumb( scrollOrientation );
2555 position -= thumbSize;
2566 int scrollOrientation =
event.GetOrientation();
2568 int position = GetScrollPos( scrollOrientation );
2570 int thumbSize = GetScrollThumb( scrollOrientation );
2572 int scrollRange = GetScrollRange( scrollOrientation );
2575 position += thumbSize;
2577 if( position > (scrollRange - thumbSize) )
2578 position = scrollRange - thumbSize;
2586 int scrollOrientation =
event.GetOrientation();
2588 int position = GetScrollPos( scrollOrientation );
2602 int scrollOrientation =
event.GetOrientation();
2604 int position = GetScrollPos( scrollOrientation );
2606 int thumbSize = GetScrollThumb( scrollOrientation );
2608 int scrollRange = GetScrollRange( scrollOrientation );
2613 if( position > (scrollRange - thumbSize) )
2614 position = scrollRange - thumbSize;
2628 int scrollOrientation =
event.GetOrientation();
2630 int thumbSize = GetScrollThumb( scrollOrientation );
2632 int scrollRange = GetScrollRange( scrollOrientation );
2634 DoScrollCalc( scrollRange - thumbSize, scrollOrientation );
2653 unsigned int layerNo = 0;
2657 if( layer->HasBBox() )
2667 if( ( position >= (
int)
m_layers.size() ) || position < 0 )
2678 if( !layer->GetName().Cmp(
name ) )
2700 if( imageSize == wxDefaultSize )
2707 sizeX = imageSize.x;
2708 sizeY = imageSize.y;
2712 wxBitmap screenBuffer( sizeX, sizeY );
2713 wxMemoryDC screenDC;
2714 screenDC.SelectObject( screenBuffer );
2715 screenDC.SetPen( *wxWHITE_PEN );
2717 wxBrush brush( GetBackgroundColour() );
2718 screenDC.SetBrush( brush );
2719 screenDC.DrawRectangle( 0, 0, sizeX, sizeY );
2728 layer->Plot( screenDC, *
this );
2730 if( imageSize != wxDefaultSize )
2735 SetScr( bk_scrX, bk_scrY );
2741 wxImage screenImage = screenBuffer.ConvertToImage();
2742 return screenImage.SaveFile( filename, type );
2759 if( layer->IsInfo() )
2763 if( tmpLyr->
Inside( point ) )
2813 const wxColour& axesColour )
2815 SetBackgroundColour( bgColour );
2816 SetForegroundColour( drawColour );
2826 wxPen axisPen = layer->GetPen();
2827 axisPen.SetColour( axesColour );
2828 layer->SetPen( axisPen );
2833 wxPen infoPen = layer->GetPen();
2834 infoPen.SetColour( drawColour );
2835 layer->SetPen( infoPen );
2886 double xlogmin = log10(
m_minV );
2887 double xlogmax = log10(
m_maxV );
2889 return ( log10( x ) - xlogmin) / (xlogmax - xlogmin);
2895 double xlogmin = log10(
m_minV );
2896 double xlogmax = log10(
m_maxV );
2898 return pow( 10.0, xplot * (xlogmax - xlogmin) + xlogmin );
2903mpFSemiLogXVector::mpFSemiLogXVector( wxString
name,
int flags ) :
2909IMPLEMENT_DYNAMIC_CLASS( mpFSemiLogXVector,
mpFXYVector )
2948 if( xs.size() != ys.size() )
2963 for(
const double x : xs )
2972 for(
const double y : ys )
3006 if( offsetx >= 0 && offsetx <= 100 )
3007 m_offsetx = offsetx;
3011 if( offsety >= 0 && offsety <= 100 )
3012 m_offsety = offsety;
3031 wxCoord tw = 0, th = 0;
3032 dc.GetTextExtent(
GetName(), &tw, &th );
3044 dc.DrawText(
GetName(), px, py );
3063 wxDC* trgDc = GetDC();
3065 if( (trgDc) && (page == 1) )
3067 wxCoord m_prnX, m_prnY;
3070 trgDc->GetSize( &m_prnX, &m_prnY );
3072 m_prnX -= (2 * marginX);
3073 m_prnY -= (2 * marginY);
3074 trgDc->SetDeviceOrigin( marginX, marginY );
3086 wxColour oldBgColour =
plotWindow->GetBackgroundColour();
3087 wxColour oldFgColour =
plotWindow->GetForegroundColour();
3091 trgDc->SetPen( *wxTRANSPARENT_PEN );
3093 wxBrush brush = *wxWHITE_BRUSH;
3094 trgDc->SetBrush( brush );
3095 trgDc->DrawRectangle( 0, 0, m_prnX, m_prnY );
3157 std::vector<double>::iterator itXi, itXo;
3158 std::vector<double>::iterator itYi, itYo;
3203 if(
m_pen.GetWidth() <= 1 )
3207 dc.DrawPoint( w.
x2p( *(itX++) ), w.
y2p( *(itY++) ) );
3214 wxCoord cx = w.
x2p( *(itX++) );
3215 wxCoord cy = w.
y2p( *(itY++) );
3216 dc.DrawLine( cx, cy, cx, cy );
3222 wxCoord cx0 = 0, cy0 = 0;
3227 wxCoord cx = w.
x2p( *(itX++) );
3228 wxCoord cy = w.
y2p( *(itY++) );
3236 dc.DrawLine( cx0, cy0, cx, cy );
3246 dc.GetTextExtent(
m_name, &tx, &ty );
3258 const int sx = w.
GetScrX() >> 1;
3259 const int sy = w.
GetScrY() >> 1;
3283 dc.DrawText(
m_name, tx, ty );
3317 double D = b * b - 4 * c;
3322 double eigenVal0 = 0.5 * ( -b + sqrt(
D ) );
3323 double eigenVal1 = 0.5 * ( -b - sqrt(
D ) );
3327 double eigenVec0_x, eigenVec0_y;
3328 double eigenVec1_x, eigenVec1_y;
3330 if( fabs( eigenVal0 -
m_cov_00 ) > 1e-6 )
3334 eigenVec0_x = eigenVec0_y * k1x;
3340 eigenVec0_y = eigenVec0_x * k1y;
3343 if( fabs( eigenVal1 -
m_cov_00 ) > 1e-6 )
3347 eigenVec1_x = eigenVec1_y * k2x;
3353 eigenVec1_y = eigenVec1_x * k2y;
3357 double len = sqrt( eigenVec0_x * eigenVec0_x + eigenVec0_y * eigenVec0_y );
3361 len = sqrt( eigenVec1_x * eigenVec1_x + eigenVec1_y * eigenVec1_y );
3367 eigenVal0 = sqrt( eigenVal0 );
3368 eigenVal1 = sqrt( eigenVal1 );
3371 double M_00 = eigenVec0_x * eigenVal0;
3372 double M_01 = eigenVec0_y * eigenVal0;
3374 double M_10 = eigenVec1_x * eigenVal1;
3375 double M_11 = eigenVec1_y * eigenVal1;
3379 double Aang = 6.283185308 / (
m_segments - 1);
3382 for( i = 0, ang = 0; i <
m_segments; i++, ang += Aang )
3384 double ccos = cos( ang );
3385 double csin = sin( ang );
3399 const std::vector<double>& points_ys,
3402 if( points_xs.size() == points_ys.size() )
3407 if( closedShape && !points_xs.empty() )
3471 double screenPixelX = ( x1 - x0 ) / (
double)
m_bitmap.GetWidth();
3472 double screenPixelY = ( y1 - y0 ) / (
double)
m_bitmap.GetHeight();
3475 wxCoord borderMarginX = (wxCoord) (screenPixelX + 1);
3476 wxCoord borderMarginY = (wxCoord) (screenPixelY + 1);
3479 wxCoord dx0 = x0, dx1 = x1, dy0 = y0, dy1 = y1;
3482 dx0 = -borderMarginX;
3485 dy0 = -borderMarginY;
3488 dx1 = w.
GetScrX() + borderMarginX;
3491 dy1 = w.
GetScrY() + borderMarginY;
3494 wxCoord d_width = dx1 - dx0 + 1;
3495 wxCoord d_height = dy1 - dy0 + 1;
3498 wxCoord offset_x = (wxCoord) ( (dx0 - x0) / screenPixelX );
3499 wxCoord offset_y = (wxCoord) ( (dy0 - y0) / screenPixelY );
3502 wxCoord b_width = (wxCoord) ( (dx1 - dx0 + 1) / screenPixelX );
3503 wxCoord b_height = (wxCoord) ( (dy1 - dy0 + 1) / screenPixelY );
3506 if( d_width>0 && d_height>0 )
3514 wxRect r( wxRect( offset_x, offset_y, b_width, b_height ) );
3526 if( r.height>
m_bitmap.GetHeight() )
3530 wxBitmap(
m_bitmap ).GetSubBitmap( r ).ConvertToImage()
3531 .Scale( d_width, d_height ) );
3547 dc.GetTextExtent(
m_name, &tx, &ty );
3559 const int sx = w.
GetScrX() >> 1;
3560 const int sy = w.
GetScrY() >> 1;
3584 dc.DrawText(
m_name, tx, ty );
void SetBitmap(const wxImage &inBmp, double x, double y, double lx, double ly)
Change the bitmap associated with the layer (to update the screen, refresh the mpWindow).
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot given view of layer to the given device context.
double m_min_x
The shape of the bitmap:
void GetBitmapCopy(wxImage &outBmp) const
Returns a copy of the current bitmap assigned to the layer.
wxImage m_bitmap
The internal copy of the Bitmap:
virtual bool HasBBox() const override
Check whether this layer has a bounding box.
wxCoord m_scaledBitmap_offset_x
wxCoord m_scaledBitmap_offset_y
double m_cov_00
The elements of the matrix (only 3 since cov(0,1)=cov(1,0) in any positive definite matrix).
void RecalculateShape()
Called to update the m_shape_xs, m_shape_ys vectors, whenever a parameter changes.
int m_segments
The number of line segments that build up the ellipse.
A class providing graphs functionality for a 2D plot (either continuous or a set of points),...
bool GetNextXY(double &x, double &y) override
Get locus value for next N.
std::vector< double > m_ys
double m_minX
Loaded at SetData.
std::vector< double > m_xs
The internal copy of the set of data to draw.
virtual void SetData(const std::vector< double > &xs, const std::vector< double > &ys)
Changes the internal data: the set of points to draw.
void Clear()
Clears all the data, leaving the layer empty.
void Rewind() override
Rewind value enumeration with mpFXY::GetNextXY.
size_t GetCount() const override
size_t m_index
The internal counter for the "GetNextXY" interface.
Abstract base class providing plot and labeling functionality for a locus plot F:N->X,...
double s2y(double plotCoordY) const
virtual void SetScale(mpScaleBase *scaleX, mpScaleBase *scaleY)
virtual void Rewind()=0
Rewind value enumeration with mpFXY::GetNextXY.
virtual size_t GetCount() const =0
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
double y2s(double y) const
void UpdateViewBoundary(wxCoord xnew, wxCoord ynew)
Update label positioning data.
double x2s(double x) const
double s2x(double plotCoordX) const
virtual bool GetNextXY(double &x, double &y)=0
Get locus value for next N.
Abstract base class providing plot and labeling functionality for functions F:X->Y.
virtual double GetY(double x) const =0
Get function value for argument.
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
Abstract base class providing plot and labeling functionality for functions F:Y->X.
virtual double GetX(double y) const =0
Get function value for argument.
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot method.
~mpInfoCoords()
Default destructor.
virtual void UpdateInfo(mpWindow &w, wxEvent &event) override
Updates the content of the info box.
mpInfoCoords()
Default constructor.
Base class to create small rectangular info boxes mpInfoLayer is the base class to create a small rec...
virtual ~mpInfoLayer()
Destructor.
virtual void UpdateInfo(mpWindow &w, wxEvent &event)
Updates the content of the info box.
mpInfoLayer()
Default constructor.
wxPoint GetPosition() const
Returns the position of the upper left corner of the box (in pixels)
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot method.
virtual void UpdateReference()
Updates the rectangle reference point.
virtual bool Inside(const wxPoint &point) const
Checks whether a point is inside the info box rectangle.
virtual void Move(wxPoint delta)
Moves the layer rectangle of given pixel deltas.
wxSize GetSize() const
Returns the size of the box (in pixels)
Implements the legend to be added to the plot This layer allows you to add a legend to describe the p...
mpInfoLegend()
Default constructor.
virtual void UpdateInfo(mpWindow &w, wxEvent &event) override
Updates the content of the info box.
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot method.
~mpInfoLegend()
Default destructor.
const wxString & GetDisplayName() const
virtual void Plot(wxDC &dc, mpWindow &w)=0
Plot given view of layer to the given device context.
mpLayerType GetLayerType() const
Get layer type: a Layer can be of different types: plot lines, axis, info boxes, etc,...
bool m_drawOutsideMargins
wxBitmap GetColourSquare(int side=16) const
Get a small square bitmap filled with the colour of the pen used in the layer.
bool IsVisible() const
Checks whether the layer is visible or not.
const wxString & GetName() const
Get layer name.
virtual double GetMinY() const
Get inclusive bottom border of bounding box.
const wxPen & GetPen() const
Get pen set for this layer.
void SetVisible(bool show)
Sets layer visibility.
virtual double GetMaxX() const
Get inclusive right border of bounding box.
virtual double GetMinX() const
Get inclusive left border of bounding box.
virtual double GetMaxY() const
Get inclusive top border of bounding box.
void TranslatePoint(double x, double y, double &out_x, double &out_y)
A method for 2D translation and rotation, using the current transformation stored in m_reference_x,...
std::vector< double > m_trans_shape_xs
The buffer for the translated & rotated points (to avoid recomputing them with each mpWindow refresh)...
virtual bool HasBBox() const override
Check whether this layer has a bounding box.
std::vector< double > m_shape_xs
This contains the object points, in local coordinates (to be transformed by the current transformatio...
void ShapeUpdated()
Must be called by the descendent class after updating the shape (m_shape_xs/ys), or when the transfor...
double m_bbox_min_x
The precomputed bounding box:
virtual void Plot(wxDC &dc, mpWindow &w) override
Plot given view of layer to the given device context.
double m_reference_x
The coordinates of the object (orientation "phi" is in radians).
std::vector< double > m_shape_ys
std::vector< double > m_trans_shape_ys
void setPoints(const std::vector< double > &points_xs, const std::vector< double > &points_ys, bool closedShape=true)
Set the points in the polygon.
bool OnPrintPage(int page) override
mpPrintout(mpWindow *drawWindow, const wxChar *title=_T("wxMathPlot print output"))
bool HasPage(int page) override
Abstract base class providing plot and labeling functionality for functions F:Y->X.
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
virtual double GetY(double x) const =0
Get function value for argument.
Plot layer implementing a x-scale ruler.
virtual void recalculateTicks(wxDC &dc, mpWindow &w)
void GetDataRange(double &minV, double &maxV) const
std::vector< double > m_tickValues
virtual double TransformToPlot(double x) const
std::vector< TickLabel > m_tickLabels
virtual void formatLabels()
virtual wxString getLabel(int n) const
virtual double getTickPos(int n) const
void computeLabelExtents(wxDC &dc, mpWindow &w)
virtual double getLabelPos(int n) const
void updateTickLabels(wxDC &dc, mpWindow &w)
void ExtendDataRange(double minV, double maxV)
virtual double TransformFromPlot(double xplot) const
virtual int labelCount() const
virtual void getVisibleDataRange(mpWindow &w, double &minV, double &maxV) override
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
mpScaleXLog(const wxString &name=wxT("log(X)"), int flags=mpALIGN_CENTER, bool ticks=true, unsigned int type=mpX_NORMAL)
Full constructor.
virtual double TransformFromPlot(double xplot) const override
virtual double TransformToPlot(double x) const override
void recalculateTicks(wxDC &dc, mpWindow &w) override
Layer plot handler.
virtual double TransformToPlot(double x) const override
Layer plot handler.
virtual double TransformFromPlot(double xplot) const override
virtual void recalculateTicks(wxDC &dc, mpWindow &w) override
mpScaleX(const wxString &name=wxT("X"), int flags=mpALIGN_CENTER, bool ticks=true, unsigned int type=mpX_NORMAL)
Full constructor.
Plot layer implementing a y-scale ruler.
virtual void getVisibleDataRange(mpWindow &w, double &minV, double &maxV) override
virtual double TransformFromPlot(double xplot) const override
void computeSlaveTicks(mpWindow &w)
virtual void Plot(wxDC &dc, mpWindow &w) override
Layer plot handler.
virtual void recalculateTicks(wxDC &dc, mpWindow &w) override
virtual double TransformToPlot(double x) const override
Plot layer implementing a text string.
virtual void Plot(wxDC &dc, mpWindow &w) override
Text Layer plot handler.
Canvas for plotting mpLayer implementations.
mpInfoLayer * m_movingInfoLayer
void DelAllLayers(bool alsoDeleteObject, bool refreshDisplay=true)
Remove all layers from the plot.
void SetColourTheme(const wxColour &bgColour, const wxColour &drawColour, const wxColour &axesColour)
Set Color theme.
virtual bool SetYView(double pos, double desiredMax, double desiredMin)
Applies new Y view coordinates depending on the settings.
void ZoomRect(wxPoint p0, wxPoint p1)
Zoom view fitting given coordinates to the window (p0 and p1 do not need to be in any specific order)
void OnScrollLineUp(wxScrollWinEvent &event)
int GetMarginLeft() const
bool m_enableMouseNavigation
void OnScrollPageUp(wxScrollWinEvent &event)
int GetScrX(void) const
Get current view's X dimension in device context units.
void ZoomInX()
Zoom in current view along X and refresh display.
void OnScrollTop(wxScrollWinEvent &event)
void OnPaint(wxPaintEvent &event)
void OnShowPopupMenu(wxMouseEvent &event)
const wxColour & GetAxesColour()
Get axes draw colour.
void OnLockAspect(wxCommandEvent &event)
void OnMouseMove(wxMouseEvent &event)
void DoZoomInXCalc(const int staticXpixel)
void SetMargins(int top, int right, int bottom, int left)
Set window margins, creating a blank area where some kinds of layers cannot draw.
bool m_enableMouseWheelPan
void OnScrollBottom(wxScrollWinEvent &event)
void OnScrollThumbTrack(wxScrollWinEvent &event)
double p2x(wxCoord pixelCoordX)
Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates,...
double p2y(wxCoord pixelCoordY)
Converts mpWindow (screen) pixel coordinates into graph (floating point) coordinates,...
wxCoord x2p(double x)
Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates,...
void OnMouseLeftDown(wxMouseEvent &event)
mpInfoLayer * IsInsideInfoLayer(wxPoint &point)
Check if a given point is inside the area of a mpInfoLayer and eventually returns its pointer.
unsigned int CountLayers() const
Counts the number of plot layers, excluding axes or text: this is to count only the layers which have...
double GetPosY(void) const
void OnMouseMiddleDown(wxMouseEvent &event)
void SetPosX(double posX)
Set current view's X position and refresh display.
void SetLayerVisible(const wxString &name, bool viewable)
Sets the visibility of a layer by its name.
double GetDesiredYmax() const
Returns the top layer-border coordinate that the user wants the mpWindow to show (it may be not exact...
double GetScaleX(void) const
void SetPosY(double posY)
Set current view's Y position and refresh display.
mpLayer * GetLayer(int position) const
bool SaveScreenshot(const wxString &filename, wxBitmapType type=wxBITMAP_TYPE_BMP, wxSize imageSize=wxDefaultSize, bool fit=false)
Draw the window on a wxBitmap, then save it to a file.
void ZoomIn(const wxPoint ¢erPoint=wxDefaultPosition)
Zoom into current view and refresh display.
void OnMagnify(wxMouseEvent &event)
void ZoomOut(const wxPoint ¢erPoint=wxDefaultPosition)
Zoom out current view and refresh display.
void OnZoomOut(wxCommandEvent &event)
double GetDesiredYmin() const
Returns the bottom-border layer coordinate that the user wants the mpWindow to show (it may be not ex...
virtual bool UpdateBBox()
Recalculate global layer bounding box, and save it in m_minX,...
double GetScaleY(void) const
bool CheckYLimits(double &desiredMax, double &desiredMin) const
bool DelLayer(mpLayer *layer, bool alsoDeleteObject=false, bool refreshDisplay=true)
Remove a plot layer from the canvas.
void LockAspect(bool enable=true)
Enable or disable X/Y scale aspect locking for the view.
void OnZoomIn(wxCommandEvent &event)
void UpdateAll()
Refresh display.
void OnScrollPageDown(wxScrollWinEvent &event)
wxCoord y2p(double y)
Converts graph (floating point) coordinates into mpWindow (screen) pixel coordinates,...
double GetDesiredXmax() const
Returns the right-border layer coordinate that the user wants the mpWindow to show (it may be not exa...
void OnCenter(wxCommandEvent &event)
virtual bool SetXView(double pos, double desiredMax, double desiredMin)
Applies new X view coordinates depending on the settings.
void SetScaleX(double scaleX)
Set current view's X scale and refresh display.
bool CheckXLimits(double &desiredMax, double &desiredMin) const
double GetDesiredXmin() const
Returns the left-border layer coordinate that the user wants the mpWindow to show (it may be not exac...
int GetMarginRight() const
void GetBoundingBox(double *bbox) const
Returns the bounding box coordinates.
void SetScr(int scrX, int scrY)
Set current view's dimensions in device context units.
int GetMarginBottom() const
static double zoomIncrementalFactor
This value sets the zoom steps whenever the user clicks "Zoom in/out" or performs zoom with the mouse...
int GetScrY(void) const
Get current view's Y dimension in device context units.
double m_desiredXmin
These are updated in Fit() only, and may be different from the real borders (layer coordinates) only ...
bool m_enableDoubleBuffer
void OnScrollLineDown(wxScrollWinEvent &event)
void OnFit(wxCommandEvent &event)
void OnSize(wxSizeEvent &event)
const mpLayer * GetLayerByName(const wxString &name) const
unsigned int CountAllLayers() const
Counts the number of plot layers, whether or not they have a bounding box.
double GetPosX(void) const
void OnMouseWheel(wxMouseEvent &event)
void SetPos(double posX, double posY)
Set current view's X and Y position and refresh display.
void OnMouseLeftRelease(wxMouseEvent &event)
bool AddLayer(mpLayer *layer, bool refreshDisplay=true)
Add a plot layer to the canvas.
void Fit() override
Set view to fit global bounding box of all plot layers and refresh display.
void DoScrollCalc(const int position, const int orientation)
bool IsLayerVisible(const wxString &name) const
Check whether a layer with given name is visible.
#define mpLEGEND_LINEWIDTH
#define mpSCROLL_NUM_PIXELS_PER_LINE
wxMathPlot is a framework for mathematical graph plotting in wxWindows.
#define mpALIGN_BORDER_RIGHT
Aligns Y axis to right border.
#define mpALIGN_RIGHT
Aligns label to the right.
#define mpALIGN_NW
Aligns label to north-west.
#define mpALIGN_FAR_RIGHT
Aligns label to the right of mpALIGN_RIGHT.
#define mpALIGN_SW
Aligns label to south-west.
#define mpALIGN_BORDER_TOP
Aligns X axis to top border.
#define mpALIGN_CENTER
Aligns label to the center.
#define mpALIGN_LEFT
Aligns label to the left.
#define mpALIGN_TOP
Aligns label to the top.
#define mpALIGN_BORDER_LEFT
Aligns Y axis to left border.
#define X_BORDER_SEPARATION
#define mpALIGN_SE
Aligns label to south-east.
#define Y_BORDER_SEPARATION
#define mpALIGN_NE
Aligns label to north-east.
#define mpALIGN_BOTTOM
Aligns label to the bottom.
#define mpALIGN_BORDER_BOTTOM
Aligns X axis to bottom border.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...