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