1 /*# ---------------------------------------------------------------------
3 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
6 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
7 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 # This software is governed by the CeCILL-B license under French law and
10 # abiding by the rules of distribution of free software. You can use,
11 # modify and/ or redistribute the software under the terms of the CeCILL-B
12 # license as circulated by CEA, CNRS and INRIA at the following URL
13 # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
14 # or in the file LICENSE.txt.
16 # As a counterpart to the access to the source code and rights to copy,
17 # modify and redistribute granted by the license, users are provided only
18 # with a limited warranty and the software's author, the holder of the
19 # economic rights, and the successive licensors have only limited
22 # The fact that you are presently reading this means that you have had
23 # knowledge of the CeCILL-B license and that you accept its terms.
24 # ------------------------------------------------------------------------ */
26 //----------------------------------------------------------------------------
27 // Class definition include
28 //----------------------------------------------------------------------------
29 #include "pPlotterLayer.h"
31 // ----------------------------------------------------------------------------
32 // WX headers inclusion.
33 // For compilers that support precompilation, includes <wx/wx.h>.
34 // ----------------------------------------------------------------------------
43 //----------------------------------------------------------------------------
44 // Class implementation
45 //----------------------------------------------------------------------------
47 IMPLEMENT_ABSTRACT_CLASS(pPlotterLayer, mpLayer)
48 //----------------------------------------------------------------------------
50 //----------------------------------------------------------------------------
54 *@param flags Label alignment, pass one of #mpALIGN_NE, #mpALIGN_NW, #mpALIGN_SW, #mpALIGN_SE.
56 pPlotterLayer:: pPlotterLayer(wxString name , int flags )
60 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
61 #if wxMAJOR_VERSION <= 2
62 points.DeleteContents(TRUE);
71 Draw the line from (x1,y1) to (x2,y2) only passing by the
72 positive points in the line
74 void pPlotterLayer::draw(wxDC & dc,mpWindow & w,double x1,double y1,double x2,double y2, int orgy)
78 float m=((float)(y2-y1))/(x2-x1);
82 double sizedc = dc.GetSize().GetHeight()-orgy;
89 dc.DrawLine(0,GetYTranslated(sizedc,y0), x2,GetYTranslated(sizedc,y2));
91 else if(y2<=0 && y1>=0)
94 dc.DrawLine(0,GetYTranslated(sizedc,y0),x0,GetYTranslated(sizedc,0) );
96 else if(y2>=0 && y1<=0)
99 dc.DrawLine(0,GetYTranslated(sizedc,y0),x2,GetYTranslated(sizedc,y2) );
107 dc.DrawLine(x1,GetYTranslated(sizedc,y1), x2,GetYTranslated(sizedc,y2));
108 else if(y1>=0 && y2<=0)
109 dc.DrawLine(x1,GetYTranslated(sizedc,y1),x0,GetYTranslated(sizedc,0) );
110 else if(y1<=0 && y2>=0)
111 dc.DrawLine(x0,GetYTranslated(sizedc,0),x2,GetYTranslated(sizedc,y2));
118 * Draw the function with th spline points
121 void pPlotterLayer::drawSplineCurve(wxDC & dc,mpWindow & w, int orgy)
123 std::vector<double> vx=getXSpline();
124 std::vector<double> vy=getYSpline();
127 int /*counter=0,*/ minX,maxX,minY,maxY; // JPRx
129 This is the offset of every point scale to the window
132 int offsetpx=getOffsetPixelsXv();
133 int offsetpy=getOffsetPixelsYv();
140 getMaxShowed(maxX,maxY);
141 getMinShowed(minX,minY);
148 Fill the function if it represented an histogram
150 ppoints=(wxPoint*)malloc(sizeof(int)*2*(vx.size()+2));
161 for(int i=0;(i+1)< size;i++)
165 double cxi=(vx.at(i)-minX-offsetX)*scaleX+offsetpx;
166 double cyi=(vy.at(i)-minY-offsetY)*scaleY+offsetpy;
168 double cxj=(vx.at(i+1)-minX-offsetX)*scaleX+offsetpx;
169 double cyj=(vy.at(i+1)-minY-offsetY)*scaleY+offsetpy;
173 draw(dc,w,cxi,cyi,cxj,cyj,orgy);
176 if(!initializePolygon(ppoints,cxi,cyi,cxj,cyj) && ((cxi<=0 && cxj>=0)||(cxi>=0 && cxj>=0)))
189 //point.x=vx.at(size-1)* scaleX + offsetpx;
190 point.x=ppoints[j-1].x;
192 //ppoints[vx.size()]=point;
195 Fill the function if it represented an histogram
197 //ppoints=(wxPoint*)malloc(sizeof(int)*2*(vx.size()+1));
199 //point.x=vx.at(0)*scaleX + offsetpx;
200 point.x=ppoints[0].x;
202 //ppoints[vx.size()+1]=point;
205 dc.SetBrush(wxBrush( wxColour(239,238,242) ,wxSOLID ));
206 dc.SetPen(wxPen( wxColour(0,0,0) ,1,wxSOLID ));
207 //dc.DrawPolygon(vx.size()+2,ppoints,0,0);
208 for(int i = 0; i <= j + 1; i++){
209 int sizedc = dc.GetSize().GetHeight()-orgy;
210 ppoints[i].y = GetYTranslated(sizedc, ppoints[i].y);
212 dc.DrawPolygon(j+2,ppoints,0,0);
219 it define the first point of the polygon for be drawing
220 returns true if the first and second point of the polygon are set
222 bool pPlotterLayer::initializePolygon(wxPoint* points,double x1, double y1,double x2, double y2)
227 float m=((float)(y2-y1))/(x2-x1);
231 if(points[0].x<=0&& points[1].x<=0 && points[0].y<=0&& points[1].y<=0)
234 //int offsetpx=getOffsetPixelsXv(); //JPRx
236 //analyzing the curve
242 //dc.DrawLine(0,y0, x2,y2);
250 else if(y2<=0 && y1>=0)
254 //dc.DrawLine(0,y0,x0,0 );
264 else if(y2>=0 && y1<=0)
268 //dc.DrawLine(0,y0,x2,y2 );
283 //dc.DrawLine(x1,y1, x2,y2);
290 else if(y1>=0 && y2<=0)
292 //dc.DrawLine(x1,y1,x0,0 );
299 else if(y1<=0 && y2>=0)
301 //dc.DrawLine(x0,0,x2,y2);
318 * Draw the lines between the points of the function
320 void pPlotterLayer::drawFunction(wxDC & dc,mpWindow & w, int orgy)
322 int scrwX,scrwY,offsetpx,offsetpy,maxX,minX,maxY,minY;
323 wxPoint* ppoints = NULL;
326 This is the offset of every point scale to the window
329 offsetpx = getOffsetPixelsXv();
330 offsetpy = getOffsetPixelsYv();
332 dc.GetSize(&scrwX, &scrwY);
333 //Lines between the points
334 int sizedc = dc.GetSize().GetHeight()-orgy;
335 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
336 #if wxMAJOR_VERSION <= 2
344 getMaxShowed(maxX,maxY);
345 getMinShowed(minX,minY);
349 //int xTraslation=getXTraslation(); //JPRx
350 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
351 #if wxMAJOR_VERSION <= 2
352 wxNode* node= points.GetFirst();
354 wxNode* node= GetPointsPtr()->GetFirst();
356 // int i=1;//points.GetCount()+1; //JPRx
359 Fill it if it is an histogram
362 // pFunctionPoint* pointk; //JPRx
366 Fill the function if it represented an histogram
368 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
369 #if wxMAJOR_VERSION <= 2
370 ppoints = (wxPoint*)malloc(sizeof(int)*2*(points.GetCount()+2));
372 ppoints = (wxPoint*)malloc(sizeof(int)*2*(GetPointsPtr()->GetCount()+2));
376 point.y = GetYTranslated(sizedc,-5000);
381 while (node!=NULL && node->GetNext()!=NULL)
383 pFunctionPoint* pointi=(pFunctionPoint*)node->GetData();
384 wxNode* nextNode=node->GetNext();
385 pFunctionPoint* pointj=(pFunctionPoint*)nextNode->GetData();
388 int pxi=(pointi->getRealX()-minX)-offsetX;
389 int pyi=(pointi->getRealY()-minY)-offsetY;
390 int pxj=(pointj->getRealX()-minX)-offsetX;
391 int pyj=(pointj->getRealY()-minY)-offsetY;
392 int cxi=pxi* scaleX + offsetpx; //+ xTraslation;
393 int cxj=pxj* scaleX + offsetpx; //+ xTraslation;
394 int cyi=pyi* scaleY+ offsetpy ;
395 int cyj=pyj* scaleY+ offsetpy ;
396 //dc.DrawLine(pxi* scaleX + offsetpx,pyi* scaleY+ offsetpy, pxj* scaleX + offsetpx,pyj* scaleY+ offsetpy );
399 draw(dc,w,pxi* scaleX + offsetpx,pyi* scaleY+ offsetpy, pxj* scaleX + offsetpx,pyj* scaleY+ offsetpy,orgy );
400 //dc.DrawLine(pxi* scaleX + offsetpx,pyi* scaleY+ offsetpy, pxj* scaleX + offsetpx,pyj* scaleY+ offsetpy );
402 if(!initializePolygon(ppoints,cxi,cyi,cxj,cyj) && ((cxi<=0 && cxj>=0)||(cxi>=0 && cxj>=0)))
405 point.y=GetYTranslated(sizedc,cyj);
411 node=node->GetNext();
415 //point.x=vx.at(size-1)* scaleX + offsetpx;
416 point.x=ppoints[j-1].x;
417 point.y=GetYTranslated(sizedc,0);
418 //ppoints[vx.size()]=point;
421 Fill the function if it represented an histogram
423 //ppoints=(wxPoint*)malloc(sizeof(int)*2*(vx.size()+1));
425 //point.x=vx.at(0)*scaleX + offsetpx;
426 point.x=ppoints[0].x;
427 point.y=GetYTranslated(sizedc,0);
428 //ppoints[vx.size()+1]=point;
431 dc.SetBrush(wxBrush( wxColour(239,238,242) ,wxSOLID ));
432 dc.SetPen(wxPen( wxColour(0,0,0) ,1,wxSOLID ));
433 //dc.DrawPolygon(vx.size()+2,ppoints,0,0);
434 dc.DrawPolygon(j+2,ppoints,0,0);
439 * Draw the points of the function
441 void pPlotterLayer::drawPoints(wxDC & dc,mpWindow & w, int orgy)
446 int minX,maxX,minY,maxY;
448 double sizedc = dc.GetSize().GetHeight()-orgy;
451 This is the offset of every point scale to the window
454 int offsetpx=getOffsetPixelsXv();
455 int offsetpy=getOffsetPixelsYv();
457 // int xTraslation=getXTraslation(); //EED
458 /*wxPen mypen(*wxBLACK, 5, wxSOLID);
461 getMaxShowed(maxX,maxY);
462 getMinShowed(minX,minY);
464 //we have to draw the points
466 while (GetNextXY(x, y))
469 //set the points of the polygons
471 dc.SetBrush(wxBrush( wxColour(255,0,0),wxSOLID ));
472 //dc.SetPen(wxPen(wxColour(0,0,0),1,wxSOLID) );
473 points[0].x=((x-minX-offsetX)*scaleX + offsetpx-MOVE);
474 points[0].y=GetYTranslated(sizedc,((y-minY-offsetY)*scaleY+ offsetpy-MOVE));
475 points[1].x=((x-minX-offsetX)*scaleX+ offsetpx+MOVE);
476 points[1].y=GetYTranslated(sizedc,((y-minY-offsetY)*scaleY+ offsetpy-MOVE));
477 points[2].x=((x-minX-offsetX)*scaleX+ offsetpx+MOVE);
478 points[2].y=GetYTranslated(sizedc,((y-minY-offsetY)*scaleY+ offsetpy+MOVE));
479 points[3].x=((x-minX-offsetX)*scaleX+ offsetpx-MOVE);
480 points[3].y=GetYTranslated(sizedc,((y-minY-offsetY)*scaleY+ offsetpy+MOVE));
481 if((x-minX-offsetX)*scaleX >=0 && (y-minY-offsetY/*w.getMinScrY()*/)*scaleY>=0)
482 dc.DrawPolygon(4,points,0,0);
487 * Draw the line between the last point of the function
488 * and the position of the mouse
490 void pPlotterLayer::drawLineToMousePoint(wxDC & dc,mpWindow & w, int orgy)
492 int x,y,sizeP,maxX,maxY,minX,minY;
498 getDirection(direction);
500 //Lines betwen the points
502 //EED 2017-09-16 Migration wxWidgets 2.8 to 3.0
503 #if wxMAJOR_VERSION <= 2
505 wxNode *node = points.GetLast();
506 wxNode *node1 = points.GetFirst();
508 wxNode *node = GetPointsPtr()->GetLast();
509 wxNode *node1 = GetPointsPtr()->GetFirst();
514 This is the offset of every point scale to the window
517 int offsetpx = getOffsetPixelsXv();
518 int offsetpy = getOffsetPixelsYv();
520 getMaxShowed(maxX,maxY);
521 getMinShowed(minX,minY);
524 // int xTraslation=getXTraslation(); //EED
528 pFunctionPoint* lastPoint=(pFunctionPoint*)node->GetData();
529 pFunctionPoint* firstPoint=(pFunctionPoint*)node1->GetData();
532 if(lastPoint->getRealX()<x && direction && sizeP >=2)
534 dc.DrawLine((lastPoint->getRealX()-minX-offsetX)*scaleX + offsetpx,(lastPoint->getRealY()-minY-offsetY)*scaleY+ offsetpy, (x-minX)*scaleX + offsetpx, (y-minY)*scaleY + offsetpy);
537 else if(firstPoint->getRealX()>x && !direction && sizeP >=2 )
539 dc.DrawLine((firstPoint->getRealX()-minX-offsetX)*scaleX+ offsetpx,(firstPoint->getRealY()-minY-offsetY)*scaleY+ offsetpy,(x-minX)*scaleX+ offsetpx, (y-minY)*scaleY+ offsetpy);
544 dc.DrawLine((lastPoint->getRealX()-minX-offsetX)*scaleX + offsetpx,(lastPoint->getRealY()-minY-offsetY)*scaleY+ offsetpy, (x-minX)*scaleX+ offsetpx, (y-minY)*scaleY+ offsetpy);
548 if( w.drawGuideLines() )
550 dc.SetPen(wxPen( wxColour(255,0,0),1,wxDOT ));
551 // Drawing the horizontal guide line
552 dc.DrawLine( 0, (y-minY)*scaleY + offsetpy, (x-minX)*scaleX + offsetpx, (y-minY)*scaleY + offsetpy);
553 // Drawing the vertical guide line
554 dc.DrawLine( (x-minX)*scaleX + offsetpx,0, (x-minX)*scaleX + offsetpx, (y-minY)*scaleY + offsetpy);
561 This implementation will plot the locus in the visible area and
562 put a label according to the aligment specified.
564 void pPlotterLayer::Plot(wxDC & dc, mpWindow & w)
566 bool show,drawing,actual;
567 int scrwX,scrwY,maxX,maxY,minX,minY,type;
577 * Managing the scale and zoom
580 dc.GetSize(&scrwX, &scrwY);
583 //getMax(maxX, maxY);
585 getMaxShowed(maxX,maxY);
586 getMinShowed(minX,minY);
588 getFactorZoom(factorZoom);
589 getOffsets(offsetX,offsetY);
596 if((maxX-minX)!=0 && (maxY-minY)!=0)
599 scaleX=(((double)scrwX-100)/(maxX-minX))*factorZoom;
600 scaleY=(((double)scrwY-50)/(maxY-minY))*factorZoom;
606 //w.setMinScrX(offsetX);
607 //w.setMinScrY(offsetY);
618 // int orgy=w.GetScrY()-40;
619 // dc.SetDeviceOrigin( orgx ,orgy);
620 // dc.SetAxisOrientation(true,true);
623 //dc.SetDeviceOrigin( orgx ,orgy);
624 dc.SetDeviceOrigin( orgx ,0);
625 int sizedc = dc.GetSize().GetHeight()-orgy;
626 //dc.SetAxisOrientation(true,false);
630 //if the user dont want to see the points of the function and if he stops drawing
631 //we have to draw the function
632 if(!show && !drawing && type==1)
633 drawFunction(dc,w,orgy);
634 else if(!show && !drawing && type==2)
635 drawSplineCurve(dc,w,orgy);
636 //we just draw the point that the user just clicked
637 else if(drawing && type==1)
639 drawFunction(dc,w,orgy);
640 drawLineToMousePoint(dc,w,orgy);
641 drawPoints(dc,w,orgy);
643 else if(drawing && type==1)
645 drawSplineCurve(dc,w,orgy);
646 drawLineToMousePoint(dc,w,orgy);
647 drawPoints(dc,w,orgy);
649 else if(show && type==1)
651 drawFunction(dc,w,orgy);
652 drawPoints(dc,w,orgy);
654 else if(show && type==2)
656 drawSplineCurve(dc,w,orgy);
657 drawPoints(dc,w,orgy);
660 // Drawing the guides according to real values entered according to the integrated interaction (IS NOT WORKING!!!)
663 dc.SetPen(wxPen( wxColour(255,0,0),1,wxDOT ));
664 int offsetpx = getOffsetPixelsXv();
665 // int offsetpy = getOffsetPixelsYv(); //EED
667 int realX_guide = w.getRealGuideX();
668 if( realX_guide!=-1 )
670 dc.DrawLine( (realX_guide/*-w.getMinScrX()*/-offsetX)*scaleX + offsetpx,
671 GetYTranslated(sizedc,0),
672 (realX_guide/*-w.getMinScrX()*/-offsetX)*scaleX + offsetpx,
673 GetYTranslated(sizedc,scrwY));
676 int realY_guide = w.getRealGuideY();
677 if( realY_guide!=-1 )
680 GetYTranslated(sizedc,(realY_guide/*-w.getMinScrY()*/-offsetX)*scaleX + offsetpx),
682 GetYTranslated(sizedc,(realY_guide/*-w.getMinScrY()*/-offsetX)*scaleX + offsetpx));