ViSP  2.8.0
vpPlotGraph.cpp
1 /****************************************************************************
2  *
3  * $Id: vpPlotGraph.cpp 4303 2013-07-04 14:14:00Z fspindle $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2013 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Define a graph for the vpPlot class.
36  *
37  * Authors:
38  * Nicolas Melchior
39  *
40  *****************************************************************************/
41 #define FLUSH_ON_PLOT
42 
43 #include <visp/vpConfig.h>
44 #ifndef DOXYGEN_SHOULD_SKIP_THIS
45 
46 #include <visp/vpPlotGraph.h>
47 #include <visp/vpMath.h>
48 #include <visp/vpMeterPixelConversion.h>
49 #include <visp/vpPixelMeterConversion.h>
50 #include <visp/vpPose.h>
51 
52 #include <visp/vpDisplayOpenCV.h>
53 #include <visp/vpDisplayX.h>
54 #include <visp/vpDisplayGDI.h>
55 #include <visp/vpDisplayGTK.h>
56 #include <visp/vpDisplayD3D.h>
57 
58 #include <cmath> // std::fabs
59 #include <visp/vpMath.h>
60 #include <limits> // numeric_limits
61 
62 #if defined(VISP_HAVE_DISPLAY)
63 
64 vpPlotGraph::vpPlotGraph()
65 {
66  curveList = NULL;
67 
68  gridColor.setColor(200,200,200);
69 
70  nbDivisionx = 10;
71  nbDivisiony = 10;
72  nbDivisionz = 10;
73 
74  xmax = 10;
75  xmin = 0;
76  ymax = 10;
77  ymin = -10;
78  zmax = 10;
79  zmin = -10;
80  xdelt = 1;
81  ydelt = 1;
82  zdelt = 1;
83  gridx = true;
84  gridy = true;
85  scaleInitialized = false;
86  firstPoint = true;
87 
88  dispUnit = false;
89  dispTitle = false;
90  dispLegend = false;
91 
92  blockedr = false;
93  blockedz = false;
94  blocked = false;
95 
96  epsi = 5;
97  epsj = 6;
98 
99  old_iPr = vpImagePoint(-1,-1);
100  old_iPz = vpImagePoint(-1,-1);
101 
102  gridThickness = 1;
103 }
104 
105 vpPlotGraph::~vpPlotGraph()
106 {
107  if (curveList != NULL)
108  {
109  delete[] curveList;
110  curveList = NULL;
111  }
112 }
113 
114 void
115 vpPlotGraph::initGraph (unsigned int nbCurve)
116 {
117  curveList = new vpPlotCurve[nbCurve];
118  curveNbr = nbCurve;
119 
121 
122  for (unsigned int i = 0; i < curveNbr; i++)
123  {
124  (curveList+i)->color = colors[i%6];
125  (curveList+i)->curveStyle = line;
126  (curveList+i)->pointListx.clear();
127  (curveList+i)->pointListy.clear();
128  strcpy((curveList+i)->legend,"");
129  }
130 }
131 
132 void
133 vpPlotGraph::initSize (vpImagePoint topLeft, unsigned int width, unsigned int height, unsigned int margei, unsigned int margej)
134 {
135  this->topLeft = topLeft;
136  this->width = width;
137  this->height = height;
138  graphZone.setTopLeft(topLeft);
139  graphZone.setWidth(width);
140  graphZone.setHeight(height);
141 
142  this->dTopLeft = vpImagePoint(topLeft.get_i()+margei,topLeft.get_j()+margej);
143  this->dWidth = width-margej-10;
144  this->dHeight = height-2*margei;
145  dGraphZone.setTopLeft(dTopLeft);
146  dGraphZone.setWidth(dWidth+1);
147  dGraphZone.setHeight(dHeight+1);
148 
149  this->dTopLeft3D = vpImagePoint(topLeft.get_i()+margei,topLeft.get_j()+10);
150  dGraphZone3D.setTopLeft(dTopLeft3D);
151  dGraphZone3D.setWidth(dWidth+1);
152  dGraphZone3D.setHeight(dHeight+1);
153 
154  if (this->dWidth > this->dHeight)
155  {
156  w_ysize = 1.0;
157  w_xsize = this->dWidth/this->dHeight;
158  w_zsize = w_xsize;
159 
160  w_yval = w_ysize/2.0;
161  w_xval = w_xsize/2.0;
162  w_zval = w_zsize/2.0;
163  }
164  else if (this->dWidth == this->dHeight)
165  {
166  w_ysize = 1.0;
167  w_xsize = 1.0;
168  w_zsize = 1.0;
169 
170  w_yval = 0.5;
171  w_xval = 0.5;
172  w_zval = 0.5;
173  }
174  else if (this->dWidth < this->dHeight)
175  {
176  w_xsize = 1.0;
177  w_ysize = this->dHeight/this->dWidth;
178  w_zsize = w_ysize;
179 
180  w_yval = w_ysize/2.0;
181  w_xval = w_xsize/2.0;
182  w_zval = w_zsize/2.0;
183  }
184 
185  cam.initPersProjWithoutDistortion(1000,1000,this->dWidth/2.0,this->dHeight/2.0);
186 
187  findPose();
188 
189  cMf.buildFrom(0,0,cMo[2][3],0,0,0);
190 }
191 
192 
193 void
194 vpPlotGraph::findPose()
195 {
196  vpPoint point[4];
197  point[0].setWorldCoordinates(-w_xval,-w_yval,-w_zval);
198  point[1].setWorldCoordinates(w_xval,-w_yval,-w_zval);
199  point[2].setWorldCoordinates(w_xval,w_yval,-w_zval);
200  point[3].setWorldCoordinates(-w_xval,w_yval,-w_zval);
201 
202  vpImagePoint iP[4];
203  iP[0].set_ij(0,0);
204  iP[1].set_ij(0,dWidth-1);
205  iP[2].set_ij(dHeight-1,dWidth-1);
206  iP[3].set_ij(dHeight-1,0);
207 
208  double x=0, y=0;
209  vpPose pose;
210  pose.clearPoint();
211 
212  for (unsigned int i=0 ; i < 4 ; i++)
213  {
214  vpPixelMeterConversion::convertPoint(cam, iP[i], x, y);
215  point[i].set_x(x);
216  point[i].set_y(y);
217  pose.addPoint(point[i]);
218  }
219 
220  pose.computePose(vpPose::LAGRANGE, cMo) ;
221  pose.computePose(vpPose::VIRTUAL_VS, cMo);
222 }
223 
224 void
225 vpPlotGraph::computeGraphParameters()
226 {
227  zoomx = dWidth/(xmax-xmin);
228  zoomy = dHeight/(ymax-ymin);
229  xorg = dTopLeft.get_j() - (xmin*zoomx);
230  yorg = dTopLeft.get_i() + (ymax*zoomy);
231 }
232 
233 void
234 vpPlotGraph::setCurveColor(const unsigned int curveNum, const vpColor color)
235 {
236  (curveList+curveNum)->color = color;
237 }
238 
239 void
240 vpPlotGraph::setTitle (const char *title)
241 {
242  strcpy(this->title, title);
243  dispTitle = true;
244 }
245 
246 void
247 vpPlotGraph::setUnitX (const char *unitx)
248 {
249  strcpy(this->unitx, unitx);
250  dispUnit = true;
251 }
252 
253 void
254 vpPlotGraph::setUnitY (const char *unity)
255 {
256  strcpy(this->unity, unity);
257  dispUnit = true;
258 }
259 
260 void
261 vpPlotGraph::setUnitZ (const char *unitz)
262 {
263  strcpy(this->unitz, unitz);
264  dispUnit = true;
265 }
266 
267 void
268 vpPlotGraph::setLegend (const unsigned int curveNum, const char *legend)
269 {
270  strcpy((curveList+curveNum)->legend,legend);
271  dispLegend = true;
272 }
273 
274 void
275 vpPlotGraph::setCurveThickness(const unsigned int curveNum, const unsigned int thickness)
276 {
277  (curveList+curveNum)->thickness = thickness;
278 }
279 
280 int
281 laFonctionSansNom (const double delta)
282 {
283  double d = delta;
284  int power = 0;
285  if (d < 1)
286  {
287  while (d < 1)
288  {
289  d = d * 10;
290  power++;
291  }
292  power--;
293  return power;
294  }
295 
296  if (d >= 10)
297  {
298  while (d > 10)
299  {
300  d = d / 10;
301  power--;
302  }
303  power--;
304  return power;
305  }
306 
307  return 0;
308 }
309 
310 void
311 vpPlotGraph::displayGrid (vpImage<unsigned char> &I)
312 {
313  computeGraphParameters();
314 
315  xdelt = (xmax-xmin)/nbDivisionx;
316  ydelt = (ymax-ymin)/nbDivisiony;
317 
318  double t;
319  char valeur[20];
320  int power;
321 
322  power = laFonctionSansNom(xdelt);
323  for(t=xmin;t<=xmax;t=t+xdelt)
324  {
325  double x = xorg+(zoomx*t);
326  if(gridy)
327  vpDisplay::displayDotLine(I,vpImagePoint(dTopLeft.get_i(),x), vpImagePoint(dTopLeft.get_i()+dHeight,x), gridColor, gridThickness);
328  else
329  vpDisplay::displayDotLine(I,vpImagePoint(yorg,x), vpImagePoint(yorg-3,x), vpColor::black, gridThickness);
330 
331  if (t+xdelt <= xmax+1e-10)
332  {
333  double ttemp;
334  if (power!=0)
335  ttemp = t*pow(10.0,power);
336  else ttemp = t;
337  sprintf(valeur, "%.2f", ttemp);
338 #if defined VISP_HAVE_X11
339  vpDisplay::displayCharString(I,vpImagePoint(yorg + 3*epsi,x),valeur, vpColor::black);
340 #elif defined (VISP_HAVE_GDI) || defined (VISP_HAVE_OPENCV) || defined(VISP_HAVE_D3D9) || defined(VISP_HAVE_GTK)
341  vpDisplay::displayCharString(I,vpImagePoint(yorg + epsi,x),valeur, vpColor::black);
342 #endif
343  }
344  }
345  if (power != 0)
346  {
347  sprintf(valeur, "x10e%d", -power);
348 #if defined VISP_HAVE_X11
349  vpDisplay::displayCharString(I,vpImagePoint(yorg+4*epsi,dTopLeft.get_j()+dWidth-6*epsj),valeur, vpColor::black);
350 #elif defined (VISP_HAVE_GDI) || defined (VISP_HAVE_OPENCV) || defined(VISP_HAVE_D3D9) || defined(VISP_HAVE_GTK)
351  vpDisplay::displayCharString(I,vpImagePoint(yorg+4*epsi,dTopLeft.get_j()+dWidth-10*epsj),valeur, vpColor::black);
352 #endif
353  }
354 
355  power = laFonctionSansNom(ydelt);
356  for(t=ymin;t<=ymax;t=t+ydelt)
357  {
358  double y = yorg-(zoomy*t);
359  if(gridx)
360  vpDisplay::displayDotLine(I,vpImagePoint(y,dTopLeft.get_j()), vpImagePoint(y,dTopLeft.get_j()+dWidth), gridColor, gridThickness);
361  else
362  vpDisplay::displayDotLine(I,vpImagePoint(y,xorg), vpImagePoint(y,xorg+3), vpColor::black, gridThickness);
363 
364  double ttemp;
365  if (power!=0)
366  ttemp = t*pow(10.0,power);
367  else ttemp = t;
368 
369  sprintf(valeur, "%.2f", ttemp);
370 #if defined VISP_HAVE_X11
371  vpDisplay::displayCharString(I,vpImagePoint(y+epsi,topLeft.get_j()+epsj),valeur, vpColor::black);
372 #elif defined (VISP_HAVE_GDI) || defined (VISP_HAVE_OPENCV) || defined(VISP_HAVE_D3D9) || defined(VISP_HAVE_GTK)
373  vpDisplay::displayCharString(I,vpImagePoint(y-epsi,topLeft.get_j()+epsj),valeur, vpColor::black);
374 #endif
375  }
376  if (power != 0)
377  {
378  sprintf(valeur, "x10e%d", -power);
379 #if defined VISP_HAVE_X11
380  vpDisplay::displayCharString(I,vpImagePoint(dTopLeft.get_i()-3*epsi,dTopLeft.get_j()-6*epsj),valeur, vpColor::black);
381 #elif defined (VISP_HAVE_GDI) || defined (VISP_HAVE_OPENCV) || defined(VISP_HAVE_D3D9) || defined(VISP_HAVE_GTK)
382  vpDisplay::displayCharString(I,vpImagePoint(dTopLeft.get_i()-3*epsi,dTopLeft.get_j()-6*epsj),valeur, vpColor::black);
383 #endif
384  }
385 
386  //Ligne horizontal
387  vpDisplay::displayArrow(I,vpImagePoint(yorg,dTopLeft.get_j()), vpImagePoint(yorg,dTopLeft.get_j()+dWidth), vpColor::black, 4*gridThickness, 2*gridThickness, gridThickness);
388  //Ligne verticale
389  vpDisplay::displayArrow(I, vpImagePoint(dTopLeft.get_i()+dHeight,xorg), vpImagePoint(dTopLeft.get_i(),xorg), vpColor::black, 4*gridThickness, 2*gridThickness, gridThickness);
390 
391  if (dispUnit)
392  displayUnit(I);
393  if (dispTitle)
394  displayTitle(I);
395  if (dispLegend)
396  displayLegend(I);
397 
398  //vpDisplay::flushROI(I,graphZone);
399 }
400 
401 void
402 vpPlotGraph::displayUnit (vpImage<unsigned char> &
403 #if defined(VISP_HAVE_X11) || defined (VISP_HAVE_GDI) || defined(VISP_HAVE_OPENCV) || defined(VISP_HAVE_D3D9) || defined(VISP_HAVE_GTK)
404  I
405 #endif
406  )
407 {
408  unsigned int offsetx = vpMath::minimum<unsigned int>((unsigned int)strlen(unitx), dWidth);
409 
410 #if defined VISP_HAVE_X11
411  vpDisplay::displayCharString(I,vpImagePoint(yorg-2*epsi,dTopLeft.get_j()+dWidth-offsetx*epsj),unitx, vpColor::black);
412  vpDisplay::displayCharString(I,vpImagePoint(dTopLeft.get_i(),dTopLeft.get_j()+epsj),unity, vpColor::black);
413 #elif defined (VISP_HAVE_GDI) || defined (VISP_HAVE_OPENCV) || defined(VISP_HAVE_D3D9) || defined(VISP_HAVE_GTK)
414  vpDisplay::displayCharString(I,vpImagePoint(yorg-5*epsi,dTopLeft.get_j()+dWidth-offsetx*epsj),unitx, vpColor::black);
415  vpDisplay::displayCharString(I,vpImagePoint(dTopLeft.get_i(),dTopLeft.get_j()+epsj),unity, vpColor::black);
416 #endif
417 }
418 
419 void
420 vpPlotGraph::displayTitle (vpImage<unsigned char> &I)
421 {
422  double size = (double)strlen(title);
423  size = size/2.0;
425  vpImagePoint(dTopLeft.get_i()-3*epsi,
426  dTopLeft.get_j()+dWidth/2.0-4*size),
427  title,
429 }
430 
431 void
432 vpPlotGraph::displayLegend (vpImage<unsigned char> &I)
433 {
434  size_t offsetj = 0;
435  for (unsigned int i = 0; i < curveNbr; i++) {
436  size_t offset = epsj * strlen((curveList+i)->legend);
437  offsetj = vpMath::maximum(offset, offsetj);
438  }
439  if (offsetj > dWidth) offsetj = dWidth;
440 
441  for (unsigned int i = 0; i < curveNbr; i++) {
443  vpImagePoint(dTopLeft.get_i()+i*5*epsi,
444  dTopLeft.get_j()+dWidth-offsetj),
445  (curveList+i)->legend,
446  (curveList+i)->color);
447  }
448 }
449 
450 void
451 vpPlotGraph::rescalex(unsigned int side, double extremity)
452 {
453  switch (side)
454  {
455  case 0:
456  xmin = (3*extremity-xmax)/2;
457  break;
458  case 1:
459  xmax = (3*extremity-xmin)/2;
460  break;
461  }
462 
463  xdelt = (xmax-xmin)/(double)nbDivisionx;
464 }
465 
466 void
467 vpPlotGraph::rescaley(unsigned int side, double extremity)
468 {
469  switch (side)
470  {
471  case 0:
472  ymin = (3*extremity-ymax)/2;
473  break;
474  case 1:
475  ymax = (3*extremity-ymin)/2;
476  break;
477  }
478 
479  ydelt = (ymax-ymin)/(double)nbDivisiony;
480 }
481 
482 void
483 vpPlotGraph::initScale(vpImage<unsigned char> &I, const double xmin, const double xmax, const int nbDivx, const double ymin, const double ymax, const int nbDivy, const bool gx, const bool gy)
484 {
485  this->xmin = xmin;
486  this->xmax = xmax;
487  this->ymin = ymin;
488  this->ymax = ymax;
489  this->gridx = gx;
490  this->gridy = gy;
491  this->nbDivisionx = nbDivx;
492  this->nbDivisiony = nbDivy;
493  computeGraphParameters();
494  clearGraphZone(I);
495  displayGrid(I);
496  vpDisplay::flushROI(I,graphZone);
497  scaleInitialized = true;
498 }
499 
500 
501 void
502 vpPlotGraph::initScale(vpImage<unsigned char> &I, const double xmin, const double xmax, const int nbDivx, const double ymin, const double ymax, const int nbDivy, const double zmin, const double zmax, const int nbDivz, const bool gx, const bool gy)
503 {
504  this->xmin = xmin;
505  this->xmax = xmax;
506  this->ymin = ymin;
507  this->ymax = ymax;
508  this->zmin = zmin;
509  this->zmax = zmax;
510  this->gridx = gx;
511  this->gridy = gy;
512  this->nbDivisionx = nbDivx;
513  this->nbDivisiony = nbDivy;
514  this->nbDivisionz = nbDivz;
515  computeGraphParameters();
516  clearGraphZone(I);
517  displayGrid(I);
518  vpDisplay::flushROI(I,graphZone);
519  scaleInitialized = true;
520 }
521 
522 void
523 vpPlotGraph::plot (vpImage<unsigned char> &I, const unsigned int curveNb, const double x, const double y)
524 {
525  if (!scaleInitialized)
526  {
527  if (x < 0)
528  {
529  xmax = 0;
530  rescalex(0,x);
531  }
532  if (x > 0)
533  {
534  xmin = 0;
535  rescalex(1,x);
536  }
537  if (y < 0)
538  {
539  ymax = 0;
540  rescaley(0,y);
541  }
542  if (y > 0)
543  {
544  ymin = 0;
545  rescaley(1,y);
546  }
547  scaleInitialized = true;
548  computeGraphParameters();
549  clearGraphZone(I);
550  displayGrid(I);
551  //if (y == 0)
552  if (std::fabs(y) <= std::numeric_limits<double>::epsilon())
553  scaleInitialized = false;
554  }
555 
556  if (firstPoint)
557  {
558 // clearGraphZone(I);
559 // displayGrid(I);
560 // vpDisplay::flushROI(I,graphZone);
561  replot(I);
562  firstPoint = false;
563  }
564 
565  double i = yorg-(zoomy*y);
566  double j = xorg+(zoomx*x);
567 
568  vpImagePoint iP(i,j);
569 
570  if (!iP.inRectangle(dGraphZone))
571  {
572  if (x > xmax) rescalex(1,x);
573  else if(x < xmin) rescalex(0,x);
574 
575  if (y > ymax) rescaley(1,y);
576  else if(y < ymin) rescaley(0,y);
577 
578  computeGraphParameters();
579 
580  replot(I);
581  i = yorg-(zoomy*y);
582  j = xorg+(zoomx*x);
583 
584  iP.set_ij(i,j);
585  }
586 
587  (curveList+curveNb)->plotPoint(I, iP, x, y);
588 #if (!defined VISP_HAVE_X11 && defined FLUSH_ON_PLOT)
589  vpDisplay::flushROI(I,graphZone);
590  //vpDisplay::flush(I);
591 #endif
592 }
593 
594 void
595 vpPlotGraph::replot (vpImage<unsigned char> &I)
596 {
597  clearGraphZone(I);
598  displayGrid(I);
599  for (unsigned int i = 0; i < curveNbr; i++)
600  (curveList+i)->plotList(I,xorg,yorg,zoomx,zoomy);
601  vpDisplay::flushROI(I,graphZone);
602 }
603 
604 void
605 vpPlotGraph::clearGraphZone(vpImage<unsigned char> &I)
606 {
607  vpDisplay::displayROI(I,graphZone);
608 }
609 
610 bool
611 vpPlotGraph::getPixelValue(vpImage<unsigned char> &I, vpImagePoint &iP)
612 {
613  if (iP.inRectangle(dGraphZone))
614  {
615  double x = (iP.get_j()-xorg)/zoomx;
616  double y = (yorg-iP.get_i())/zoomy;
617 
618  vpDisplay::displayROI(I,vpRect(vpImagePoint(topLeft.get_i()+height-20,topLeft.get_j()),width-1,19));
619  char valeur[200];
620  sprintf(valeur, " x: %f", x);
621  vpDisplay::displayCharString(I,vpImagePoint(topLeft.get_i()+height-2,topLeft.get_j()+5*epsj),valeur, vpColor::black);
622  sprintf(valeur, " y: %f", y);
623  vpDisplay::displayCharString(I,vpImagePoint(topLeft.get_i()+height-2,topLeft.get_j()+width/2.0),valeur, vpColor::black);
624 // vpDisplay::flush(I);
625  vpDisplay::flushROI(I,vpRect(vpImagePoint(topLeft.get_i()+height-20,topLeft.get_j()),width-1,19));
626  return true;
627  }
628  return false;
629 }
630 
631 void
632 vpPlotGraph::resetPointList(const unsigned int curveNum)
633 {
634  (curveList+curveNum)->pointListx.clear();
635  (curveList+curveNum)->pointListy.clear();
636  (curveList+curveNum)->pointListz.clear();
637  (curveList+curveNum)->nbPoint = 0;
638  firstPoint = true;
639 }
640 
641 
642 /************************************************************************************************/
643 
644 bool
645 vpPlotGraph::check3Dline(vpImagePoint &iP1, vpImagePoint &iP2)
646 {
647  bool iP1In = iP1.inRectangle(dGraphZone3D);
648  bool iP2In = iP2.inRectangle(dGraphZone3D);
649 
650  if (!iP1In || !iP2In)
651  {
652  double dTopLeft_i = dTopLeft3D.get_i();
653  double dTopLeft_j = dTopLeft3D.get_j();
654  double dBottomRight_i = dTopLeft_i+dHeight;
655  double dBottomRight_j = dTopLeft_j+dWidth;
656 
657  //Cas vertical
658  if (vpImagePoint::distance(iP1,iP2) < 9)
659  return false;
660  if (fabs(iP2.get_j()-iP1.get_j()) <=2)
661  {
662  if (!iP1In && !iP2In)
663  {
664  if (iP1.get_i() < dTopLeft_i && iP2.get_i() < dTopLeft_i)
665  return false;
666  if (iP1.get_i() > dBottomRight_i && iP2.get_i() > dBottomRight_i)
667  return false;
668  if (iP1.get_j() < dTopLeft_j || iP1.get_j() > dBottomRight_j)
669  return false;
670  if (iP1.get_i() < dTopLeft_i) iP1.set_i(dTopLeft_i);
671  else iP1.set_i(dBottomRight_i);
672  if (iP2.get_i() < dTopLeft_i) iP2.set_i(dTopLeft_i);
673  else iP2.set_i(dBottomRight_i);
674  }
675  else if (!iP1In)
676  {
677  if (iP1.get_j() < dTopLeft_j) iP1.set_j(dTopLeft_j);
678  if (iP1.get_j() > dBottomRight_j) iP1.set_j(dBottomRight_j);
679  if (iP1.get_i() < dTopLeft_i) iP1.set_i(dTopLeft_i);
680  if (iP1.get_i() > dBottomRight_i) iP1.set_i(dBottomRight_i);
681  return true;
682  }
683  else if (!iP2In)
684  {
685  if (iP2.get_j() < dTopLeft_j) iP2.set_j(dTopLeft_j);
686  if (iP2.get_j() > dBottomRight_j) iP2.set_j(dBottomRight_j);
687  if (iP2.get_i() < dTopLeft_i) iP2.set_i(dTopLeft_i);
688  if (iP2.get_i() > dBottomRight_i) iP2.set_i(dBottomRight_i);
689  return true;
690  }
691  }
692  //cas horizontal
693  else if (fabs(iP2.get_i()-iP1.get_i()) <= 2)
694  {
695  if (!iP1In && !iP2In)
696  {
697  if (iP1.get_j() < dTopLeft_j && iP2.get_j() < dTopLeft_j)
698  return false;
699  if (iP1.get_j() > dBottomRight_j && iP2.get_j() > dBottomRight_j)
700  return false;
701  if (iP1.get_i() < dTopLeft_i || iP1.get_i() > dBottomRight_i)
702  return false;
703  if (iP1.get_j() < dTopLeft_j) iP1.set_j(dTopLeft_j);
704  else iP1.set_j(dBottomRight_j);
705  if (iP2.get_j() < dTopLeft_j) iP2.set_j(dTopLeft_j);
706  else iP2.set_j(dBottomRight_j);
707  }
708  else if (!iP1In)
709  {
710  if (iP1.get_j() < dTopLeft_j) iP1.set_j(dTopLeft_j);
711  if (iP1.get_j() > dBottomRight_j) iP1.set_j(dBottomRight_j);
712  if (iP1.get_i() < dTopLeft_i) iP1.set_i(dTopLeft_i);
713  if (iP1.get_i() > dBottomRight_i) iP1.set_i(dBottomRight_i);
714  return true;
715  }
716  else if (!iP2In)
717  {
718  if (iP2.get_j() < dTopLeft_j) iP2.set_j(dTopLeft_j);
719  if (iP2.get_j() > dBottomRight_j) iP2.set_j(dBottomRight_j);
720  if (iP2.get_i() < dTopLeft_i) iP2.set_i(dTopLeft_i);
721  if (iP2.get_i() > dBottomRight_i) iP2.set_i(dBottomRight_i);
722  return true;
723  }
724  }
725 
726  double a = (iP2.get_i()-iP1.get_i())/(iP2.get_j()-iP1.get_j());
727  double b = iP1.get_i()-a*iP1.get_j();
728 
729  //test horizontal
730  double jtop = (dTopLeft_i-b)/a;
731  double jlow = (dBottomRight_i-b)/a;
732  //test vertical
733  double ileft = dTopLeft_j*a+b;
734  double iright = (dBottomRight_j)*a+b;
735 
736  vpImagePoint iP[2];
737  int n = 0;
738 
739  if(jtop >= dTopLeft_j && jtop <= dBottomRight_j)
740  {
741  iP[n].set_ij(dTopLeft_i,jtop);
742  n++;
743  }
744  if(jlow >= dTopLeft_j && jlow <= dBottomRight_j)
745  {
746  iP[n].set_ij(dBottomRight_i,jlow);
747  n++;
748  }
749  if(ileft >= dTopLeft_i && ileft <= dBottomRight_i && n <2)
750  {
751  iP[n].set_ij(ileft,dTopLeft_j);
752  n++;
753  }
754  if(iright >= dTopLeft_i && iright <= dBottomRight_i && n <2)
755  {
756  iP[n].set_ij(iright,dBottomRight_j);
757  n++;
758  }
759 
760  if (n < 2)
761  return false;
762 
763  if (!iP1In && !iP2In)
764  {
765  if (fabs(a) < 1)
766  {
767  if (vpMath::sign(iP1.get_j()-iP[0].get_j()) == vpMath::sign(iP2.get_j()-iP[0].get_j()))
768  return false;
769  int sign = vpMath::sign(iP1.get_j() - iP2.get_j());
770  if (sign == vpMath::sign(iP[0].get_j()-iP[1].get_j()))
771  {
772  iP1 = iP[0]; iP2 = iP[1];
773  }
774  else
775  {
776  iP1 = iP[1]; iP2 = iP[0];
777  }
778  }
779  else
780  {
781  if (vpMath::sign(iP1.get_i()-iP[0].get_i()) == vpMath::sign(iP2.get_i()-iP[0].get_i()))
782  return false;
783  int sign = vpMath::sign(iP1.get_i() - iP2.get_i());
784  if (sign == vpMath::sign(iP[0].get_i()-iP[1].get_i()))
785  {
786  iP1 = iP[0];iP2 = iP[1];
787  }
788  else
789  {
790  iP1 = iP[1];iP2 = iP[0];
791  }
792  }
793  }
794  else if (!iP1In)
795  {
796  vpImagePoint iPtemp = iP1;
797  if (fabs(a) < 1)
798  {
799  int sign = vpMath::sign(iP1.get_j() - iP2.get_j());
800  if (fabs(iP[0].get_j()-iP2.get_j()) > 5)
801  {
802  if (sign == vpMath::sign(iP[0].get_j()-iP2.get_j())) iP1 = iP[0];
803  else iP1 = iP[1];
804  }
805  else
806  {
807  if (sign == vpMath::sign(iP[1].get_j()-iP2.get_j())) iP1 = iP[1];
808  else iP1 = iP[0];
809  }
810  }
811  else
812  {
813  int sign = vpMath::sign(iP1.get_i() - iP2.get_i());
814  if (fabs(iP[0].get_i()-iP2.get_i()) > 5)
815  {
816  if (sign == vpMath::sign(iP[0].get_i()-iP2.get_i())) iP1 = iP[0];
817  else iP1 = iP[1];
818  }
819  else
820  {
821  if (sign == vpMath::sign(iP[1].get_i()-iP2.get_i())) iP1 = iP[1];
822  else iP1 = iP[0];
823  }
824  }
825  if (vpImagePoint::distance(iP1,iP2) < 9)
826  {
827  iP1 = iPtemp;
828  return false;
829  }
830  }
831  else if (!iP2In)
832  {
833  vpImagePoint iPtemp = iP2;
834  if (fabs(a) < 1)
835  {
836  int sign = vpMath::sign(iP2.get_j() - iP1.get_j());
837  if (fabs(iP[0].get_j()-iP1.get_j()) > 5)
838  {
839  if (sign == vpMath::sign(iP[0].get_j()-iP1.get_j())) iP2 = iP[0];
840  else iP2 = iP[1];
841  }
842  else
843  {
844  if (sign == vpMath::sign(iP[1].get_j()-iP1.get_j())) iP2 = iP[1];
845  else iP2 = iP[0];
846  }
847  }
848  else
849  {
850  int sign = vpMath::sign(iP2.get_i() - iP1.get_i());
851  if (fabs(iP[0].get_i()-iP1.get_i()) > 5)
852  {
853  if (sign == vpMath::sign(iP[0].get_i()-iP1.get_i())) iP2 = iP[0];
854  else iP2 = iP[1];
855  }
856  else
857  {
858  if (sign == vpMath::sign(iP[1].get_i()-iP1.get_i())) iP2 = iP[1];
859  else iP2 = iP[0];
860  }
861  }
862  if (vpImagePoint::distance(iP1,iP2) < 9)
863  {
864  iP2 = iPtemp;
865  return false;
866  }
867  }
868  }
869  return true;
870 }
871 
872 bool
873 vpPlotGraph::check3Dpoint(vpImagePoint &iP)
874 {
875  if (!iP.inRectangle(dGraphZone3D))
876  {
877  if (iP.get_i() < dTopLeft3D.get_i())
878  iP.set_i(dTopLeft3D.get_i());
879  else if (iP.get_i() > dTopLeft3D.get_i()+dHeight)
880  iP.set_i(dTopLeft3D.get_i()+dHeight-1);
881  if (iP.get_j() <dTopLeft3D.get_j())
882  iP.set_j(dTopLeft3D.get_j());
883  else if (iP.get_j() > dTopLeft3D.get_j()+dWidth)
884  iP.set_i(dTopLeft3D.get_j()+dWidth-1);
885  return false;
886  }
887  return true;
888 }
889 
890 void
891 vpPlotGraph::computeGraphParameters3D()
892 {
893  zoomx_3D = w_xsize/(xmax-xmin);
894  zoomy_3D = w_ysize/(ymax-ymin);
895  zoomz_3D = w_zsize/(zmax-zmin);
896  ptXorg = w_xval - zoomx_3D*xmax;
897  ptYorg = w_yval + zoomy_3D*ymin;
898  ptZorg = w_zval - zoomz_3D*zmax;
899 }
900 
901 void getGrid3DPoint(const double pente, vpImagePoint &iPunit, vpImagePoint &ip1, vpImagePoint &ip2, vpImagePoint &ip3)
902 {
903  if (pente <= 1)
904  {
905  ip1 = iPunit-vpImagePoint(3,0);
906  ip2 = iPunit+vpImagePoint(3,0);
907  ip3 = iPunit-vpImagePoint(6,6);
908  }
909  else
910  {
911  ip1 = iPunit-vpImagePoint(0,3);
912  ip2 = iPunit+vpImagePoint(0,3);
913  ip3 = iPunit+vpImagePoint(6,6);
914  }
915 }
916 
917 void
918 vpPlotGraph::displayGrid3D (vpImage<unsigned char> &I)
919 {
920  computeGraphParameters3D();
921 
922  xdelt = (xmax-xmin)/nbDivisionx;
923  ydelt = (ymax-ymin)/nbDivisiony;
924  zdelt = (zmax-zmin)/nbDivisionz;
925 
926  vpPoint pt[6];
927  pt[0].setWorldCoordinates(-w_xval,ptYorg,ptZorg);
928  pt[1].setWorldCoordinates(w_xval,ptYorg,ptZorg);
929  pt[2].setWorldCoordinates(ptXorg,-w_yval,ptZorg);
930  pt[3].setWorldCoordinates(ptXorg,w_yval,ptZorg);
931  pt[4].setWorldCoordinates(ptXorg,ptYorg,-w_zval);
932  pt[5].setWorldCoordinates(ptXorg,ptYorg,w_zval);
933 
934  vpImagePoint iP[6];
935  for (unsigned int i = 0; i < 6; i++)
936  {
937  pt[i].track(cMo);
938  double u=0.0,v=0.0;
939  vpMeterPixelConversion::convertPoint(cam,pt[i].get_x(),pt[i].get_y(),u,v);
940  iP[i].set_uv(u,v);
941  iP[i] = iP[i] + dTopLeft3D;
942  }
943 
944  int power;
945  double t;
946  char valeur[20];
947  vpPoint ptunit;
948  vpImagePoint iPunit;
949  double pente;
950  vpImagePoint ip1;
951  vpImagePoint ip2;
952  vpImagePoint ip3;
953  vpImagePoint ip4;
954 
955  power = laFonctionSansNom(xdelt);
956  ptunit.setWorldCoordinates(-w_xval,ptYorg,ptZorg);
957  //if (iP[0].get_j()-iP[1].get_j() != 0)
958  if (std::fabs(iP[0].get_j()-iP[1].get_j()) >
959  vpMath::maximum(std::fabs(iP[0].get_j()), std::fabs(iP[1].get_j()))* std::numeric_limits<double>::epsilon())
960  pente = fabs((iP[0].get_i()-iP[1].get_i())/(iP[0].get_j()-iP[1].get_j()));
961  else pente = 2;
962 
963  unsigned int count = 1;
964  for(t=xmin;t<=xmax;t=t+xdelt)
965  {
966  double x = ptXorg+(zoomx_3D*t);
967  ptunit.set_oX(x);
968  ptunit.track(cMo);
969  double u=0.0, v=0.0;
970  vpMeterPixelConversion::convertPoint(cam,ptunit.get_x(),ptunit.get_y(),u,v);
971  iPunit.set_uv(u,v);
972  iPunit = iPunit + dTopLeft3D;
973 
974  getGrid3DPoint(pente,iPunit,ip1,ip2,ip3);
975 
976  if(check3Dline(ip1,ip2))
977  {
979  if (count%2 == 1)
980  {
981  double ttemp;
982  if (power!=0)
983  ttemp = t*pow(10.0,power);
984  else ttemp = t;
985  sprintf(valeur, "%.1f", ttemp);
987  }
988  }
989  count++;
990  }
991  if (power != 0)
992  {
993  ip4 = iP[1] -vpImagePoint(-15,10);
994  sprintf(valeur, "x10e%d", -power);
995  if(check3Dpoint(ip4))
997  }
998 
999  power = laFonctionSansNom(ydelt);
1000  ptunit.setWorldCoordinates(ptXorg,-w_yval,ptZorg);
1001  //if (iP[2].get_j()-iP[3].get_j() != 0)
1002  if (std::fabs(iP[2].get_j()-iP[3].get_j()) >
1003  vpMath::maximum(std::fabs(iP[2].get_j()), std::fabs(iP[3].get_j()))* std::numeric_limits<double>::epsilon())
1004  pente = fabs((iP[2].get_i()-iP[3].get_i())/(iP[2].get_j()-iP[3].get_j()));
1005  else pente = 2;
1006  count = 0;
1007  for(t=ymin;t<=ymax;t=t+ydelt)
1008  {
1009  double y = ptYorg-(zoomy_3D*t);
1010  ptunit.set_oY(y);
1011  ptunit.track(cMo);
1012  double u=0.0, v=0.0;
1013  vpMeterPixelConversion::convertPoint(cam,ptunit.get_x(),ptunit.get_y(),u,v);
1014  iPunit.set_uv(u,v);
1015  iPunit = iPunit + dTopLeft3D;
1016 
1017  getGrid3DPoint(pente,iPunit,ip1,ip2,ip3);
1018 
1019  if(check3Dline(ip1,ip2))
1020  {
1022  if (count%2 == 1)
1023  {
1024  double ttemp;
1025  if (power!=0)
1026  ttemp = t*pow(10.0,power);
1027  else ttemp = t;
1028  sprintf(valeur, "%.1f", ttemp);
1030  }
1031  }
1032  count++;
1033  }
1034  if (power != 0)
1035  {
1036  ip4 = iP[2] -vpImagePoint(-15,10);
1037  sprintf(valeur, "x10e%d", -power);
1038  if(check3Dpoint(ip4))
1040  }
1041 
1042  power = laFonctionSansNom(zdelt);
1043  ptunit.setWorldCoordinates(ptXorg,ptYorg,-w_zval);
1044  //if (iP[4].get_j()-iP[5].get_j() != 0)
1045  if (std::fabs(iP[4].get_j()-iP[5].get_j()) >
1046  vpMath::maximum(std::fabs(iP[4].get_j()), std::fabs(iP[5].get_j()))* std::numeric_limits<double>::epsilon())
1047  pente = fabs((iP[4].get_i()-iP[5].get_i())/(iP[4].get_j()-iP[5].get_j()));
1048  else pente = 2;
1049  count = 0;
1050  for(t=zmin;t<=zmax;t=t+zdelt)
1051  {
1052  double z = ptZorg+(zoomz_3D*t);
1053  ptunit.set_oZ(z);
1054  ptunit.track(cMo);
1055  double u=0.0, v=0.0;
1056  vpMeterPixelConversion::convertPoint(cam,ptunit.get_x(),ptunit.get_y(),u,v);
1057  iPunit.set_uv(u,v);
1058  iPunit = iPunit + dTopLeft3D;
1059 
1060  getGrid3DPoint(pente,iPunit,ip1,ip2,ip3);
1061 
1062  if(check3Dline(ip1,ip2))
1063  {
1065  if (count%2 == 1)
1066  {
1067  double ttemp;
1068  if (power!=0)
1069  ttemp = t*pow(10.0,power);
1070  else ttemp = t;
1071  sprintf(valeur, "%.1f", ttemp);
1073  }
1074  }
1075  count++;
1076  }
1077  if (power != 0)
1078  {
1079  ip4 = iP[5] -vpImagePoint(-15,10);
1080  sprintf(valeur, "x10e%d", -power);
1081  if(check3Dpoint(ip4))
1083  }
1084 
1085 
1086 //Ligne horizontal
1087  if (check3Dline(iP[0],iP[1]))
1088  {
1089  vpDisplay::displayArrow(I,iP[0],iP[1], vpColor::black, gridThickness);
1090  if (dispUnit)
1091  {
1092  vpImagePoint iPunit(iP[1].get_i(),iP[1].get_j()-10*epsj);
1093  check3Dpoint (iPunit);
1095  }
1096  }
1097  if (check3Dline(iP[3],iP[2]))
1098  {
1099  vpDisplay::displayArrow(I,iP[3],iP[2], vpColor::black, gridThickness);
1100  if (dispUnit)
1101  {
1102  vpImagePoint iPunit(iP[2].get_i(),iP[2].get_j()-10*epsj);
1103  check3Dpoint (iPunit);
1105  }
1106  }
1107  if (check3Dline(iP[4],iP[5]))
1108  {
1109  vpDisplay::displayArrow(I,iP[4],iP[5], vpColor::black, gridThickness);
1110  if (dispUnit)
1111  {
1112  vpImagePoint iPunit(iP[5].get_i(),iP[5].get_j()-10*epsj);
1113  check3Dpoint (iPunit);
1115  }
1116  }
1117 
1118  if (dispTitle)
1119  displayTitle(I);
1120  if (dispLegend)
1121  displayLegend(I);
1122 }
1123 
1124 void
1125 vpPlotGraph::plot (vpImage<unsigned char> &I, const unsigned int curveNb, const double x, const double y, const double z)
1126 {
1127  if (!scaleInitialized)
1128  {
1129  if (x < 0)
1130  {
1131  xmax = 0;
1132  rescalex(0,x);
1133  }
1134  if (x > 0)
1135  {
1136  xmin = 0;
1137  rescalex(1,x);
1138  }
1139  if (y < 0)
1140  {
1141  ymax = 0;
1142  rescaley(0,y);
1143  }
1144  if (y > 0)
1145  {
1146  ymin = 0;
1147  rescaley(1,y);
1148  }
1149  if (z < 0)
1150  {
1151  zmax = 0;
1152  rescalez(0,z);
1153  }
1154  if (z > 0)
1155  {
1156  zmin = 0;
1157  rescalez(1,z);
1158  }
1159  scaleInitialized = true;
1160  computeGraphParameters3D();
1161  clearGraphZone(I);
1162  displayGrid3D(I);
1163  //if (std::fabs(y) == 0 || z == 0)
1164  if (std::fabs(y) <= std::numeric_limits<double>::epsilon() || std::fabs(z) <= std::numeric_limits<double>::epsilon())
1165  scaleInitialized = false;
1166  }
1167 
1168  if (firstPoint)
1169  {
1170  clearGraphZone(I);
1171  displayGrid3D(I);
1172  vpDisplay::flushROI(I,graphZone);
1173  firstPoint = false;
1174  }
1175 
1176  bool changed = false;
1177  if (x > xmax) {rescalex(1,x); changed = true;}
1178  else if(x < xmin) {rescalex(0,x);changed = true;}
1179 
1180  if (y > ymax) {rescaley(1,y);changed = true;}
1181  else if(y < ymin) {rescaley(0,y);changed = true;}
1182 
1183  if (z > zmax) {rescalez(1,z);changed = true;}
1184  else if(z < zmin) {rescalez(0,z);changed = true;}
1185 
1186  if (changed || move(I))
1187  {
1188  computeGraphParameters3D();
1189  replot3D(I);
1190  }
1191 
1192  vpPoint pointPlot;
1193  pointPlot.setWorldCoordinates(ptXorg+(zoomx_3D*x),ptYorg-(zoomy_3D*y),ptZorg+(zoomz_3D*z));
1194  pointPlot.track(cMo);
1195  double u=0.0, v=0.0;
1196  vpMeterPixelConversion::convertPoint(cam,pointPlot.get_x(),pointPlot.get_y(),u,v);
1197  vpImagePoint iP;
1198  iP.set_uv(u,v);
1199  iP = iP + dTopLeft3D;
1200 
1201  (curveList+curveNb)->pointListx.end();
1202  (curveList+curveNb)->pointListy.end();
1203  (curveList+curveNb)->pointListz.end();
1204  if((curveList+curveNb)->nbPoint)
1205  {
1206  if (check3Dline((curveList+curveNb)->lastPoint,iP))
1207  vpDisplay::displayLine(I,(curveList+curveNb)->lastPoint, iP, (curveList+curveNb)->color, (curveList+curveNb)->thickness);
1208  }
1209 #if( defined VISP_HAVE_X11 || defined VISP_HAVE_GDI )
1210  double top;
1211  double left;
1212  double width;
1213  double height;
1214 
1215  if (iP.get_i() <= (curveList+curveNb)->lastPoint.get_i()) {top = iP.get_i()-5; height = (curveList+curveNb)->lastPoint.get_i() - top+10;}
1216  else {top = (curveList+curveNb)->lastPoint.get_i()-5; height = iP.get_i() - top+10;}
1217  if (iP.get_j() <= (curveList+curveNb)->lastPoint.get_j()) {left = iP.get_j()-5; width = (curveList+curveNb)->lastPoint.get_j() - left+10;}
1218  else {left = (curveList+curveNb)->lastPoint.get_j()-5; width = iP.get_j() - left+10;}
1219  vpDisplay::flushROI(I,vpRect(left,top,width,height));
1220 #endif
1221 
1222  (curveList+curveNb)->lastPoint = iP;
1223  (curveList+curveNb)->pointListx.push_back(x);
1224  (curveList+curveNb)->pointListy.push_back(y);
1225  (curveList+curveNb)->pointListz.push_back(z);
1226  (curveList+curveNb)->nbPoint++;
1227 
1228 
1229 #if( !defined VISP_HAVE_X11 && defined FLUSH_ON_PLOT)
1230  vpDisplay::flushROI(I,graphZone);
1231 #endif
1232 }
1233 
1234 void
1235 vpPlotGraph::replot3D (vpImage<unsigned char> &I)
1236 {
1237  clearGraphZone(I);
1238  displayGrid3D(I);
1239 
1240  for (unsigned int i = 0; i < curveNbr; i++)
1241  {
1242  std::list<double>::const_iterator it_ptListx = (curveList+i)->pointListx.begin();
1243  std::list<double>::const_iterator it_ptListy = (curveList+i)->pointListy.begin();
1244  std::list<double>::const_iterator it_ptListz = (curveList+i)->pointListz.begin();
1245 
1246  unsigned int k = 0;
1247  vpImagePoint iP;
1248  vpPoint pointPlot;
1249  double x,y,z;
1250  while (k < (curveList+i)->nbPoint)
1251  {
1252  x = *it_ptListx;
1253  y = *it_ptListy;
1254  z = *it_ptListz;
1255  pointPlot.setWorldCoordinates(ptXorg+(zoomx_3D*x),ptYorg-(zoomy_3D*y),ptZorg+(zoomz_3D*z));
1256  pointPlot.track(cMo);
1257  double u=0.0, v=0.0;
1258  vpMeterPixelConversion::convertPoint(cam,pointPlot.get_x(),pointPlot.get_y(),u,v);
1259  iP.set_uv(u,v);
1260  iP = iP + dTopLeft3D;
1261 
1262  //vpDisplay::displayCross(I,iP,3,vpColor::cyan);
1263  if (k > 0)
1264  {
1265  if (check3Dline((curveList+i)->lastPoint,iP))
1266  vpDisplay::displayLine(I,(curveList+i)->lastPoint, iP, (curveList+i)->color);
1267  //vpDisplay::displayCross(I,iP,3,vpColor::orange);
1268  }
1269 
1270  (curveList+i)->lastPoint = iP;
1271 
1272  ++it_ptListx;
1273  ++it_ptListy;
1274  ++it_ptListz;
1275  k++;
1276  }
1277  }
1278  vpDisplay::flushROI(I,graphZone);
1279 }
1280 
1281 
1282 
1283 void
1284 vpPlotGraph::rescalez(unsigned int side, double extremity)
1285 {
1286  switch (side)
1287  {
1288  case 0:
1289  zmin = (3*extremity-zmax)/2;
1290  break;
1291  case 1:
1292  zmax = (3*extremity-zmin)/2;
1293  break;
1294  }
1295 
1296  zdelt = (zmax-zmin)/(double)nbDivisionz;
1297 }
1298 
1299 bool
1300 vpPlotGraph::move(const vpImage<unsigned char> &I)
1301 {
1302  bool changed = false;
1303  vpHomogeneousMatrix displacement = navigation(I,changed);
1304 
1305  //if (displacement[2][3] != 0)
1306  if (std::fabs(displacement[2][3]) > std::numeric_limits<double>::epsilon())
1307  cMf = cMf*displacement;
1308  vpHomogeneousMatrix fMo = cMf.inverse()*cMo;
1309 
1310  cMo = cMf* displacement * fMo;
1311  return changed;
1312 }
1313 
1315 vpPlotGraph::navigation(const vpImage<unsigned char> &I, bool &changed)
1316 {
1317  vpImagePoint iP;
1318  vpImagePoint trash;
1319  bool clicked = false;
1320  bool clickedUp = false;
1322 
1323  vpHomogeneousMatrix mov(0,0,0,0,0,0);
1324  changed = false;
1325 
1326  //if(!blocked) vpDisplay::getClickUp(I,trash, b,false);
1327 
1328  if(!blocked) clicked = vpDisplay::getClick(I,iP,b,false);
1329 
1330  if(blocked) clickedUp = vpDisplay::getClickUp(I,trash, b,false);
1331 
1332  if (clicked)
1333  {
1334  if (!iP.inRectangle(graphZone))
1335  return mov;
1336  }
1337 
1338  if(clicked)
1339  {
1340  if (b == vpMouseButton::button1) blockedr = true;
1341  if (b == vpMouseButton::button2) blockedz = true;
1342  blocked = true;
1343  }
1344 
1345  else if(clickedUp)
1346  {
1347  if (b == vpMouseButton::button1)
1348  {
1349  old_iPr = vpImagePoint(-1,-1);
1350  blockedr = false;
1351  }
1352  if (b == vpMouseButton::button2)
1353  {
1354  old_iPz = vpImagePoint(-1,-1);
1355  blockedz = false;
1356  }
1357  if (!(blockedr || blockedz))
1358  {
1359  blocked = false;
1360  //while (vpDisplay::getClick(I,trash,b,false)) {};
1361  }
1362  }
1363 
1365 
1366  double anglei = 0;
1367  double anglej = 0;
1368 
1369  if (old_iPr != vpImagePoint(-1,-1) && blockedr)
1370  {
1371  double width = vpMath::minimum(I.getWidth(),I.getHeight());
1372 
1373  double diffi = iP.get_i() - old_iPr.get_i();
1374  double diffj = iP.get_j() - old_iPr.get_j();
1375 
1376  anglei = diffi*360/width;
1377  anglej = diffj*360/width;
1378  mov.buildFrom(0,0,0,vpMath::rad(anglei),vpMath::rad(-anglej),0);
1379  changed = true;
1380  }
1381 
1382  if (blockedr) old_iPr = iP;
1383 
1384  if (old_iPz != vpImagePoint(-1,-1) && blockedz)
1385  {
1386  double diffi = iP.get_i() - old_iPz.get_i();
1387  mov.buildFrom(0,0,diffi*0.01,0,0,0);
1388  changed = true;
1389  }
1390 
1391  if (blockedz) old_iPz = iP;
1392 
1393  return mov;
1394 }
1395 
1396 #endif
1397 #endif
void set_j(const double j)
Definition: vpImagePoint.h:156
bool inRectangle(const vpRect &rect) const
virtual void displayArrow(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color=vpColor::white, unsigned int w=4, unsigned int h=2, unsigned int thickness=1)=0
double get_i() const
Definition: vpImagePoint.h:181
unsigned int getWidth() const
Definition: vpImage.h:159
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
static const vpColor black
Definition: vpColor.h:161
static void convertPoint(const vpCameraParameters &cam, const double &x, const double &y, double &u, double &v)
Point coordinates conversion from normalized coordinates in meter to pixel coordinates ...
Class to define colors available for display functionnalities.
Definition: vpColor.h:125
void set_i(const double i)
Definition: vpImagePoint.h:145
virtual bool getClickUp(vpImagePoint &ip, vpMouseButton::vpMouseButtonType &button, bool blocking=true)=0
void set_x(const double x)
Set the point x coordinate in the image plane.
Definition: vpPoint.h:194
void track(const vpHomogeneousMatrix &cMo)
static void convertPoint(const vpCameraParameters &cam, const double &u, const double &v, double &x, double &y)
Point coordinates conversion from pixel coordinates to normalized coordinates in meter...
double get_y() const
Get the point y coordinate in the image plane.
Definition: vpPoint.h:138
static const vpColor green
Definition: vpColor.h:170
double get_j() const
Definition: vpImagePoint.h:192
void set_oX(const double X)
Set the point X coordinate in the object frame.
Definition: vpPoint.h:185
static const vpColor red
Definition: vpColor.h:167
Class that defines what is a point.
Definition: vpPoint.h:65
static Type maximum(const Type &a, const Type &b)
Definition: vpMath.h:137
static const vpColor orange
Definition: vpColor.h:177
void initPersProjWithoutDistortion(const double px, const double py, const double u0, const double v0)
static const vpColor cyan
Definition: vpColor.h:176
void set_oZ(const double Z)
Set the point Z coordinate in the object frame.
Definition: vpPoint.h:189
virtual bool getPointerPosition(vpImagePoint &ip)=0
void set_ij(const double i, const double j)
Definition: vpImagePoint.h:167
Class used for pose computation from N points (pose from point only).
Definition: vpPose.h:78
void set_y(const double y)
Set the point y coordinate in the image plane.
Definition: vpPoint.h:196
double get_x() const
Get the point x coordinate in the image plane.
Definition: vpPoint.h:136
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:148
static double rad(double deg)
Definition: vpMath.h:100
virtual void displayDotLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
virtual void displayCharString(const vpImagePoint &ip, const char *text, const vpColor &color=vpColor::green)=0
vpHomogeneousMatrix inverse() const
unsigned int getHeight() const
Definition: vpImage.h:150
void set_uv(const double u, const double v)
Definition: vpImagePoint.h:225
Defines a rectangle in the plane.
Definition: vpRect.h:82
static void flushROI(const vpImage< unsigned char > &I, const vpRect &roi)
Definition: vpDisplay.cpp:2008
void computePose(vpPoseMethodType methode, vpHomogeneousMatrix &cMo)
compute the pose for a given method
Definition: vpPose.cpp:382
static void displayROI(const vpImage< unsigned char > &I, const vpRect &roi)
Definition: vpDisplay.cpp:222
virtual bool getClick(bool blocking=true)=0
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:92
virtual void displayLine(const vpImagePoint &ip1, const vpImagePoint &ip2, const vpColor &color, unsigned int thickness=1)=0
static int sign(double x)
Definition: vpMath.h:248
void addPoint(const vpPoint &P)
Add a new point in this array.
Definition: vpPose.cpp:150
static const vpColor purple
Definition: vpColor.h:178
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
Definition: vpImagePoint.h:261
static const vpColor blue
Definition: vpColor.h:173
void setWorldCoordinates(const double ox, const double oy, const double oz)
Set the point world coordinates. We mean here the coordinates of the point in the object frame...
Definition: vpPoint.cpp:74
void set_oY(const double Y)
Set the point Y coordinate in the object frame.
Definition: vpPoint.h:187
void clearPoint()
suppress all the point in the array of point
Definition: vpPose.cpp:128