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