]> Creatis software - creaMaracasVisu.git/blob - lib/maracasVisuLib/src/interface/wxWindows/widgets/pPlotter/pPlotterLayer.cxx
creaMaracasVisu Library
[creaMaracasVisu.git] / lib / maracasVisuLib / src / interface / wxWindows / widgets / pPlotter / pPlotterLayer.cxx
1 //----------------------------------------------------------------------------
2 // Class definition include
3 //----------------------------------------------------------------------------
4 #include "pPlotterLayer.h"
5
6 // ----------------------------------------------------------------------------
7 // WX headers inclusion.
8 // For compilers that support precompilation, includes <wx/wx.h>.
9 // ----------------------------------------------------------------------------
10
11 #ifndef WX_PRECOMP
12 #include <wx/wx.h>
13 #endif
14
15 #include <vector>
16 #include <fstream>
17 #include <iostream>
18 //----------------------------------------------------------------------------
19 // Class implementation
20 //----------------------------------------------------------------------------
21
22 IMPLEMENT_ABSTRACT_CLASS(pPlotterLayer, mpLayer)
23 //----------------------------------------------------------------------------
24 // Methods
25 //----------------------------------------------------------------------------
26
27 /** 
28 *@param name  Label
29 *@param flags Label alignment, pass one of #mpALIGN_NE, #mpALIGN_NW, #mpALIGN_SW, #mpALIGN_SE.
30 */
31 pPlotterLayer:: pPlotterLayer(wxString name , int flags )
32 {
33         SetName(name);
34         m_flags = flags;
35         points.DeleteContents(TRUE);
36         offsetX=0;
37         offsetY=0;
38 }
39
40 /*
41 Draw the line from (x1,y1) to (x2,y2) only passing by the 
42 positive points in the line
43 */
44 void  pPlotterLayer::draw(wxDC & dc,mpWindow & w,double x1,double y1,double x2,double y2)
45 {
46         
47         //intercepts
48         float m=((float)(y2-y1))/(x2-x1);
49         float x0=-y1/m+x1;
50         float y0=-m*x1+y1;      
51
52
53         //analyzing the curve
54
55                 if(x1<=0 && x2>=0)
56                 {
57                         if(y2>=0 && y1>=0)
58                                         dc.DrawLine(0,y0, x2,y2);
59
60                         else if(y2<=0 && y1>=0)
61                         {
62                                 if(y0>=0 && x0>=0)
63                                         dc.DrawLine(0,y0,x0,0 );
64                         }
65                         else if(y2>=0 && y1<=0)
66                         {
67                                 if(y0>=0) 
68                                 dc.DrawLine(0,y0,x2,y2 );
69                         }
70         
71                 }
72
73                 if(x1>=0 && x2>=0)
74                 {
75                         if(y1>=0 && y2>=0 )
76                                 dc.DrawLine(x1,y1, x2,y2);
77                         else if(y1>=0 && y2<=0)
78                                 dc.DrawLine(x1,y1,x0,0 );
79                         else if(y1<=0 && y2>=0) 
80                                         dc.DrawLine(x0,0,x2,y2);
81                 }
82                 
83                 
84 }
85         
86 /**
87 * Draw the function with th spline points
88 *
89 */
90 void pPlotterLayer::drawSplineCurve(wxDC & dc,mpWindow & w)
91 {
92         std::vector<double> vx=getXSpline();
93         std::vector<double> vy=getYSpline();
94         wxPoint* ppoints;
95         
96         int counter=0,minX,maxX,minY,maxY;
97         /*
98         This is the offset of every point scale to the window
99         pixel
100         */
101         int offsetpx=getOffsetPixelsXv();
102         int offsetpy=getOffsetPixelsYv();
103         
104         // type of plotter
105         int type=getmType();
106  
107         wxPoint point;
108         /***********/
109         getMaxShowed(maxX,maxY);
110         getMinShowed(minX,minY);
111         /***********/
112
113         
114         if(type==2)
115         {
116          /*
117                 Fill the function if it represented an histogram
118           */
119                 ppoints=(wxPoint*)malloc(sizeof(int)*2*(vx.size()+2));
120                 //initialize points
121                 point.x=-5000;
122                 point.y=-5000;
123                 ppoints[0]=point;
124                 ppoints[1]=point;
125         }
126         
127         int size=vx.size();
128         int j=2;
129
130         for(int i=0;(i+1)< size;i++)
131         {
132                 
133                 
134                 double cxi=(vx.at(i)-minX-offsetX)*scaleX+offsetpx;
135                 double cyi=(vy.at(i)-minY-offsetY)*scaleY+offsetpy;
136                 
137                 double cxj=(vx.at(i+1)-minX-offsetX)*scaleX+offsetpx;
138                 double cyj=(vy.at(i+1)-minY-offsetY)*scaleY+offsetpy;
139                 
140                 
141                 if(type!=2)     
142                         draw(dc,w,cxi,cyi,cxj,cyj);
143                 else if(type==2)
144                 {
145                         if(!initializePolygon(ppoints,cxi,cyi,cxj,cyj) && ((cxi<=0 && cxj>=0)||(cxi>=0 && cxj>=0)))
146                         {
147                                         point.x=cxj;
148                                         point.y=cyj;
149                                         ppoints[j]=point;
150                                         j++;
151                 
152                         }
153                 }
154                 
155         }
156         if(type==2)
157         {
158                 //point.x=vx.at(size-1)* scaleX + offsetpx;
159                 point.x=ppoints[j-1].x;
160                 point.y=0;
161                 //ppoints[vx.size()]=point;
162                 ppoints[j]=point;
163                 /*
164                 Fill the function if it represented an histogram
165           */
166                 //ppoints=(wxPoint*)malloc(sizeof(int)*2*(vx.size()+1));
167                 //settings for fill
168                 //point.x=vx.at(0)*scaleX + offsetpx;
169                 point.x=ppoints[0].x;
170                 point.y=0;
171                 //ppoints[vx.size()+1]=point;
172                 ppoints[j+1]=point;
173
174                 dc.SetBrush(wxBrush( wxColour(239,238,242) ,wxSOLID  ));
175                 dc.SetPen(wxPen( wxColour(0,0,0) ,1,wxSOLID  ));
176                 //dc.DrawPolygon(vx.size()+2,ppoints,0,0);
177                 dc.DrawPolygon(j+2,ppoints,0,0);
178         }
179         
180         
181 }
182
183 /*
184  it define the first point of the polygon for be drawing
185  returs true if the first and second point of the polygon are setted
186 */
187 bool pPlotterLayer::initializePolygon(wxPoint* points,double x1, double y1,double x2, double y2)
188 {
189         bool setted=false;
190
191                 //intercepts
192         float m=((float)(y2-y1))/(x2-x1);
193         float x0=-y1/m+x1;
194         float y0=-m*x1+y1;      
195
196         if(points[0].x<=0&& points[1].x<=0 && points[0].y<=0&& points[1].y<=0)
197         {
198         
199                 int offsetpx=getOffsetPixelsXv();       
200
201                 //analyzing the curve
202
203                         if(x1<=0 && x2>=0)
204                         {
205                                 if(y2>=0 && y1>=0)
206                                 {
207                                                 //dc.DrawLine(0,y0, x2,y2);
208                                                 points[0].x=0;
209                                                 points[0].y=y0;
210                                                 points[1].x=x2;
211                                                 points[1].y=y2;
212                                                 setted=true;                                    
213                                         
214                                 }
215                                 else if(y2<=0 && y1>=0)
216                                 {
217                                         if(y0>=0 && x0>=0)
218                                         {
219                                                 //dc.DrawLine(0,y0,x0,0 );
220                                                 points[0].x=0;
221                                                 points[0].y=y0;
222                                                 points[1].x=x0;
223                                                 points[1].y=0;
224                                                 setted=true;    
225
226                                         }
227                                                 
228                                 }
229                                 else if(y2>=0 && y1<=0)
230                                 {       
231                                         if(y0>=0) 
232                                         {       
233                                                 //dc.DrawLine(0,y0,x2,y2 );
234                                                 points[0].x=0;
235                                                 points[0].y=y0;
236                                                 points[1].x=x2;
237                                                 points[1].y=y2;
238                                                 setted=true;    
239                                         }
240                                 }
241                 
242                         }
243
244                         if(x1>=0 && x2>=0)
245                         {
246                                 if(y1>=0 && y2>=0 )
247                                 {
248                                         //dc.DrawLine(x1,y1, x2,y2);
249                                         points[0].x=x1;
250                                         points[0].y=y1;
251                                         points[1].x=x2;
252                                         points[1].y=y2;
253                                         setted=true;    
254                                 }
255                                 else if(y1>=0 && y2<=0)
256                                 {
257                                         //dc.DrawLine(x1,y1,x0,0 );
258                                         points[0].x=x1;
259                                         points[0].y=y1;
260                                         points[1].x=x0;
261                                         points[1].y=0;
262                                         setted=true;    
263                                 }
264                                 else if(y1<=0 && y2>=0) 
265                                 {       
266                                         //dc.DrawLine(x0,0,x2,y2);
267                                         points[0].x=x0;
268                                         points[0].y=0;
269                                         points[1].x=x2;
270                                         points[1].y=y2;
271                                         setted=true;    
272                                 }
273                         }
274                         else
275                         return setted;
276         }
277         else
278                 return setted;
279 }
280
281 /**
282 * Draw le lines between the points of the function
283 */
284 void pPlotterLayer::drawFunction(wxDC & dc,mpWindow & w)
285 {
286
287         
288         int scrwX,scrwY,offsetpx,offsetpy,maxX,minX,maxY,minY;
289         wxPoint* ppoints=NULL;
290
291         /*
292         This is the offset of every point scale to the window
293         pixel
294         */
295         offsetpx=getOffsetPixelsXv();
296         offsetpy=getOffsetPixelsYv();
297         
298
299         Rewind();
300         
301
302         dc.GetSize(&scrwX, &scrwY);
303         
304         //Lines between the points
305         
306         GetPoints(points);
307
308         // type of plotter
309         int type=getmType();
310         /***********/
311         getMaxShowed(maxX,maxY);
312         getMinShowed(minX,minY);
313         /***********/
314
315         //traslation
316         int xTraslation=getXTraslation();
317         wxNode* node= points.GetFirst();
318         int i=1;//points.GetCount()+1;
319         int j=2;
320         /*
321          Fill it if it is an histogram
322         */
323         wxPoint point;
324         pFunctionPoint* pointk;
325         if(type==2)
326         {
327                 /*
328                 Fill the function if it represented an histogram
329           */
330                 ppoints=(wxPoint*)malloc(sizeof(int)*2*(points.GetCount()+2));
331                 //initialize points
332                 point.x=-5000;
333                 point.y=-5000;
334                 ppoints[0]=point;
335                 ppoints[1]=point;
336
337         }
338         
339         
340         while (node!=NULL && node->GetNext()!=NULL)
341         { 
342                 pFunctionPoint* pointi=(pFunctionPoint*)node->GetData();
343                                 wxNode* nextNode=node->GetNext();
344                 pFunctionPoint* pointj=(pFunctionPoint*)nextNode->GetData();
345                                                 
346                 // we do the offset
347                 int pxi=(pointi->getRealX()-minX)-offsetX;
348                 int pyi=(pointi->getRealY()-minY)-offsetY;
349                 int pxj=(pointj->getRealX()-minX)-offsetX;
350                 int pyj=(pointj->getRealY()-minY)-offsetY;
351
352
353                 int cxi=pxi* scaleX + offsetpx; //+ xTraslation;
354                 int cxj=pxj* scaleX + offsetpx; //+ xTraslation;
355                 int cyi=pyi* scaleY+ offsetpy ;
356                 int cyj=pyj* scaleY+ offsetpy ;
357                 //dc.DrawLine(pxi* scaleX + offsetpx,pyi* scaleY+ offsetpy, pxj* scaleX + offsetpx,pyj* scaleY+ offsetpy );
358                 if(type!=2)
359                         draw(dc,w,pxi* scaleX + offsetpx,pyi* scaleY+ offsetpy, pxj* scaleX + offsetpx,pyj* scaleY+ offsetpy );
360                         //dc.DrawLine(pxi* scaleX + offsetpx,pyi* scaleY+ offsetpy, pxj* scaleX + offsetpx,pyj* scaleY+ offsetpy );
361                 else if(type==2)
362                 {
363                         if(!initializePolygon(ppoints,cxi,cyi,cxj,cyj) && ((cxi<=0 && cxj>=0)||(cxi>=0 && cxj>=0)))
364                         {
365                                         point.x=cxj;
366                                         point.y=cyj;
367                                         ppoints[j]=point;
368                                         j++;
369                 
370                         }
371                 }
372                 
373                 node=node->GetNext();
374
375         } 
376         if(type==2)
377         {
378                 //point.x=vx.at(size-1)* scaleX + offsetpx;
379                 point.x=ppoints[j-1].x;
380                 point.y=0;
381                 //ppoints[vx.size()]=point;
382                 ppoints[j]=point;
383                 /*
384                 Fill the function if it represented an histogram
385           */
386                 //ppoints=(wxPoint*)malloc(sizeof(int)*2*(vx.size()+1));
387                 //settings for fill
388                 //point.x=vx.at(0)*scaleX + offsetpx;
389                 point.x=ppoints[0].x;
390                 point.y=0;
391                 //ppoints[vx.size()+1]=point;
392                 ppoints[j+1]=point;
393
394                 dc.SetBrush(wxBrush( wxColour(239,238,242) ,wxSOLID  ));
395                 dc.SetPen(wxPen( wxColour(0,0,0) ,1,wxSOLID  ));
396                 //dc.DrawPolygon(vx.size()+2,ppoints,0,0);
397                 dc.DrawPolygon(j+2,ppoints,0,0);
398
399         }
400         
401 }
402
403 /**
404 *  Draw the points of the function
405 */
406 void pPlotterLayer::drawPoints(wxDC & dc,mpWindow & w)
407 {
408         
409         Rewind();
410         double x, y;
411         int minX,maxX,minY,maxY;
412
413         
414         /*
415         This is the offset of every point scale to the window
416         pixel
417         */
418         int offsetpx=getOffsetPixelsXv();
419         int offsetpy=getOffsetPixelsYv();
420         //traslation
421         int xTraslation=getXTraslation();
422         /*wxPen mypen(*wxBLACK, 5, wxSOLID);
423         dc.SetPen(mypen);*/
424         /***********/
425         getMaxShowed(maxX,maxY);
426         getMinShowed(minX,minY);
427         /***********/
428         //we have to draw the points
429
430         while (GetNextXY(x, y))
431         {
432                 //GetNextXY(x, y);
433                 //set the points of the polygons
434                 wxPoint points[4];
435                 dc.SetBrush(wxBrush( wxColour(255,0,0),wxSOLID  ));
436                 //dc.SetPen(wxPen(wxColour(0,0,0),1,wxSOLID) );
437                 points[0].x=((x-minX-offsetX)*scaleX + offsetpx-MOVE);
438                 points[0].y=((y-minY-offsetY)*scaleY+ offsetpy-MOVE);
439                 points[1].x=((x-minX-offsetX)*scaleX+ offsetpx+MOVE);
440                 points[1].y=((y-minY-offsetY)*scaleY+ offsetpy-MOVE);
441                 points[2].x=((x-minX-offsetX)*scaleX+ offsetpx+MOVE);
442                 points[2].y=((y-minY-offsetY)*scaleY+ offsetpy+MOVE);
443                 points[3].x=((x-minX-offsetX)*scaleX+ offsetpx-MOVE);
444                 points[3].y=((y-minY-offsetY)*scaleY+ offsetpy+MOVE);
445                 if((x-minX-offsetX)*scaleX >=0 && (y-minY-offsetY/*w.getMinScrY()*/)*scaleY>=0)
446                 dc.DrawPolygon(4,points,0,0);
447         }
448 }
449
450 /**
451 * Draw the line between the last point of the function
452 * and the position of the mouse
453 */
454 void pPlotterLayer::drawLineToMousePoint(wxDC & dc,mpWindow & w)
455 {
456         int x,y,sizeP,maxX,maxY,minX,minY;
457         bool direction;
458         
459         Rewind();
460         
461         getMousePoint(x,y);
462         getDirection(direction);
463         getSize(sizeP);
464         //Lines betwen the points
465         GetPoints(points);
466
467         wxNode *node=points.GetLast();
468         wxNode *node1=points.GetFirst();
469         
470         
471         /*
472         This is the offset of every point scale to the window
473         pixel
474         */
475         int offsetpx = getOffsetPixelsXv();
476         int offsetpy = getOffsetPixelsYv();
477         /***********/
478         getMaxShowed(maxX,maxY);
479         getMinShowed(minX,minY);
480         /***********/
481         //traslation
482         int xTraslation=getXTraslation();
483         
484         if(node)
485         {
486                 pFunctionPoint* lastPoint=(pFunctionPoint*)node->GetData();
487                 pFunctionPoint* firstPoint=(pFunctionPoint*)node1->GetData();
488
489                 //LeftDrawing
490                 if(lastPoint->getRealX()<x && direction && sizeP >=2)
491                         
492                         dc.DrawLine((lastPoint->getRealX()-minX-offsetX)*scaleX + offsetpx,(lastPoint->getRealY()-minY-offsetY)*scaleY+ offsetpy, (x-minX)*scaleX + offsetpx, (y-minY)*scaleY + offsetpy);
493                 
494                 //right drawing
495                 else if(firstPoint->getRealX()>x && !direction && sizeP >=2 )
496                         
497                         dc.DrawLine((firstPoint->getRealX()-minX-offsetX)*scaleX+ offsetpx,(firstPoint->getRealY()-minY-offsetY)*scaleY+ offsetpy,(x-minX)*scaleX+ offsetpx, (y-minY)*scaleY+ offsetpy);
498                 
499                 //just a point
500                 else if(sizeP==1 )
501                 {
502                         dc.DrawLine((lastPoint->getRealX()-minX-offsetX)*scaleX + offsetpx,(lastPoint->getRealY()-minY-offsetY)*scaleY+ offsetpy, (x-minX)*scaleX+ offsetpx, (y-minY)*scaleY+ offsetpy);
503                 }
504         }                       
505         
506         if( w.drawGuideLines() )  
507         {
508                 dc.SetPen(wxPen(  wxColour(255,0,0),1,wxDOT ));
509                 // Drawing the horizontal guide line    
510                 dc.DrawLine( 0, (y-minY)*scaleY + offsetpy, (x-minX)*scaleX + offsetpx, (y-minY)*scaleY + offsetpy);                                    
511                 // Drawing the vertical guide line      
512                 dc.DrawLine( (x-minX)*scaleX + offsetpx,0, (x-minX)*scaleX + offsetpx, (y-minY)*scaleY + offsetpy);     
513         }
514 }
515
516
517 /** 
518 Layer plot handler.
519 This implementation will plot the locus in the visible area and
520 put a label according to the aligment specified.
521 */
522 void pPlotterLayer::Plot(wxDC & dc, mpWindow & w)
523 {
524         bool show,drawing,actual;
525         int scrwX,scrwY,maxX,maxY,minX,minY,type;
526         float factorZoom;
527         
528         ifShowPoints(show);
529         getDrawing(drawing);
530         type=vGetType();
531         
532         dc.SetPen( m_pen);
533         
534         /*
535          * Managing the scale and zoom
536          */
537         
538         dc.GetSize(&scrwX, &scrwY);
539         getIfActual(actual);
540         //getMax(maxX, maxY);
541         /***********/
542         getMaxShowed(maxX,maxY);
543         getMinShowed(minX,minY);
544         /***********/
545         getFactorZoom(factorZoom);
546         getOffsets(offsetX,offsetY);
547         /*
548         maxX=w.getMaxScrX();
549         maxY=w.getMaxScrY();
550         minX=w.getMinScrX();
551         minY=w.getMinScrY();
552         */
553         if((maxX-minX)!=0 && (maxY-minY)!=0)
554         {
555                 
556                 scaleX=(((double)scrwX-100)/(maxX-minX))*factorZoom;
557                 scaleY=(((double)scrwY-50)/(maxY-minY))*factorZoom;
558                 
559                 if(actual)
560                 {
561                         w.SetScaleX(scaleX);
562                         w.SetScaleY(scaleY);
563                         //w.setMinScrX(offsetX);
564                         //w.setMinScrY(offsetY);
565                 }
566                 
567         }
568         /*
569                 Managing the drawing
570         */
571         int orgx=70;
572         int orgy=w.GetScrY()-40;
573         dc.SetDeviceOrigin( orgx ,orgy);
574         dc.SetAxisOrientation(true,true);
575
576
577         //if the user dont want to see the points of the function and if he stops drawing
578         //we have to draw the function
579         if(!show && !drawing && type==1)
580                 drawFunction(dc,w);
581         else if(!show && !drawing && type==2)
582                 drawSplineCurve(dc,w);
583         //we just draw the point that the user just clicked
584         else if(drawing && type==1)
585         { 
586                 drawFunction(dc,w);
587                 drawLineToMousePoint(dc,w);
588                 drawPoints(dc,w);
589         }
590         else if(drawing && type==1)
591         {
592                 drawSplineCurve(dc,w);
593                 drawLineToMousePoint(dc,w);
594                 drawPoints(dc,w);
595         }
596         else if(show && type==1)
597         {
598                 drawFunction(dc,w);
599                 drawPoints(dc,w);
600         }
601         else if(show && type==2)
602         {
603                 drawSplineCurve(dc,w);
604                 drawPoints(dc,w);
605         }
606
607         // Drawing the guides according to real values entered according to the integrated interaction (IS NOT WORKING!!!)
608         if ( actual )
609         {
610                 dc.SetPen(wxPen(  wxColour(255,0,0),1,wxDOT ));
611                 int offsetpx = getOffsetPixelsXv();
612                 int offsetpy = getOffsetPixelsYv();
613
614                 int realX_guide = w.getRealGuideX();
615                 if( realX_guide!=-1 )
616                 {
617                 dc.DrawLine( (realX_guide/*-w.getMinScrX()*/-offsetX)*scaleX + offsetpx, 0, (realX_guide/*-w.getMinScrX()*/-offsetX)*scaleX + offsetpx, scrwY);                 
618                 }
619                         
620                 int realY_guide = w.getRealGuideY();
621                 if( realY_guide!=-1 )
622                 {
623                         dc.DrawLine( 0,(realY_guide/*-w.getMinScrY()*/-offsetX)*scaleX + offsetpx, scrwX, (realY_guide/*-w.getMinScrY()*/-offsetX)*scaleX + offsetpx);
624                 }
625         }
626    
627 }
628