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