Visual Servoing Platform  version 3.6.1 under development (2024-04-23)
vpPlot.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2023 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 https://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  * Plot curves.
33  *
34 *****************************************************************************/
35 
36 #include <visp3/core/vpConfig.h>
37 
38 #if defined(VISP_HAVE_DISPLAY)
39 #include <fstream>
40 #include <list>
41 #include <vector>
42 #include <visp3/core/vpMath.h>
43 #include <visp3/core/vpMeterPixelConversion.h>
44 #include <visp3/core/vpPixelMeterConversion.h>
45 #include <visp3/gui/vpDisplayD3D.h>
46 #include <visp3/gui/vpDisplayGDI.h>
47 #include <visp3/gui/vpDisplayGTK.h>
48 #include <visp3/gui/vpDisplayOpenCV.h>
49 #include <visp3/gui/vpDisplayX.h>
50 #include <visp3/gui/vpPlot.h>
51 
58 vpPlot::vpPlot() : I(), display(nullptr), graphNbr(1), graphList(nullptr), margei(30), margej(40), factori(1.f), factorj(1.)
59 { }
77 vpPlot::vpPlot(unsigned int graph_nbr, unsigned int height, unsigned int width, int x, int y, const std::string &title)
78  : I(), display(nullptr), graphNbr(1), graphList(nullptr), margei(30), margej(40), factori(1.f), factorj(1.)
79 {
80  init(graph_nbr, height, width, x, y, title);
81 }
82 
95 void vpPlot::init(unsigned int graph_nbr, unsigned int height, unsigned int width, int x, int y,
96  const std::string &title)
97 {
98  I.init(height, width, 255);
99 
100 #if defined(VISP_HAVE_X11)
101  display = new vpDisplayX;
102 #elif defined(VISP_HAVE_GDI)
103  display = new vpDisplayGDI;
104 #elif defined(HAVE_OPENCV_HIGHGUI)
105  display = new vpDisplayOpenCV;
106 #elif defined(VISP_HAVE_GTK)
107  display = new vpDisplayGTK;
108 #elif defined(VISP_HAVE_D3D9)
109  display = new vpDisplayD3D;
110 #endif
111 
112  display->init(I, x, y, title);
113 
115 
116  factori = height / 700.0f;
117  factorj = width / 700.0f;
118 
119  initNbGraph(graph_nbr);
120 }
121 
126 {
127  if (graphList != nullptr) {
128  delete[] graphList;
129  graphList = nullptr;
130  }
131  if (display != nullptr) {
132  delete display;
133  display = nullptr;
134  }
135 }
136 
146 void vpPlot::initNbGraph(unsigned int nbGraph)
147 {
148  if (nbGraph > 4) {
149  throw vpException(vpException::dimensionError, "Cannot create more than 4 graphs");
150  }
151  graphList = new vpPlotGraph[nbGraph];
152  graphNbr = nbGraph;
153 
154  switch (nbGraph) {
155  case 1:
156  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(700 * factorj), (unsigned int)(700 * factori), margei,
157  margej);
158  break;
159  case 2:
160  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(700 * factorj), (unsigned int)(350 * factori), margei,
161  margej);
162  graphList[1].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(700 * factorj),
163  (unsigned int)(350 * factori), margei, margej);
164  break;
165  case 3:
166  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei,
167  margej);
168  graphList[1].initSize(vpImagePoint(0, (unsigned int)(350 * factorj)), (unsigned int)(350 * factorj),
169  (unsigned int)(350 * factori), margei, margej);
170  graphList[2].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(700 * factorj),
171  (unsigned int)(350 * factori), margei, margej);
172  break;
173  case 4:
174  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei,
175  margej);
176  graphList[1].initSize(vpImagePoint(0, (unsigned int)(350 * factorj)), (unsigned int)(350 * factorj),
177  (unsigned int)(350 * factori), margei, margej);
178  graphList[2].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(350 * factorj),
179  (unsigned int)(350 * factori), margei, margej);
180  graphList[3].initSize(vpImagePoint((unsigned int)(350 * factori), (unsigned int)(350 * factorj)),
181  (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei, margej);
182  break;
183  }
184 
185  for (unsigned int i = 0; i < graphNbr; ++i) {
186  graphList[i].title.clear();
187  graphList[i].unitx.clear();
188  graphList[i].unity.clear();
189  graphList[i].unitz.clear();
190  }
191 }
192 
202 void vpPlot::initGraph(unsigned int graphNum, unsigned int curveNbr) { (graphList + graphNum)->initGraph(curveNbr); }
203 
214 void vpPlot::initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
215 {
216  (graphList + graphNum)->initScale(I, xmin, xmax, 10, ymin, ymax, 10, true, true);
217 }
218 
231 void vpPlot::initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax, double zmin,
232  double zmax)
233 {
234  (graphList + graphNum)->initScale(I, xmin, xmax, 10, ymin, ymax, 10, zmin, zmax, 10, true, true);
235 }
236 
245 void vpPlot::setColor(unsigned int graphNum, unsigned int curveNum, vpColor color)
246 {
247  (graphList + graphNum)->setCurveColor(curveNum, color);
248 }
249 
253 void vpPlot::displayGrid()
254 {
255  for (unsigned int i = 0; i < graphNbr; ++i)
256  graphList[i].displayGrid(I);
257 }
258 
269 void vpPlot::plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
270 {
271  (graphList + graphNum)->plot(I, curveNum, x, y);
272 }
273 
285 void vpPlot::plot(unsigned int graphNum, double x, const vpColVector &v_y)
286 {
287  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
288  for (unsigned int i = 0; i < v_y.getRows(); ++i)
289  this->plot(graphNum, i, x, v_y[i]);
290  }
291  else
292  vpTRACE("error in plot vector : not the right dimension");
293 }
306 void vpPlot::plot(unsigned int graphNum, double x, const vpRowVector &v_y)
307 {
308  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
309  for (unsigned int i = 0; i < v_y.getRows(); ++i)
310  this->plot(graphNum, i, x, v_y[i]);
311  }
312  else
313  vpTRACE("error in plot vector : not the right dimension");
314 }
315 
329 void vpPlot::plot(unsigned int graphNum, double x, const vpPoseVector &v_y)
330 {
331  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
332  for (unsigned int i = 0; i < v_y.getRows(); ++i)
333  this->plot(graphNum, i, x, v_y[i]);
334  }
335  else
336  vpTRACE("error in plot vector : not the right dimension");
337 }
351 void vpPlot::plot(unsigned int graphNum, double x, const vpTranslationVector &v_y)
352 {
353  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
354  for (unsigned int i = 0; i < v_y.getRows(); ++i)
355  this->plot(graphNum, i, x, v_y[i]);
356  }
357  else
358  vpTRACE("error in plot vector : not the right dimension");
359 }
360 
374 void vpPlot::plot(unsigned int graphNum, double x, const vpRotationVector &v_y)
375 {
376  if ((graphList + graphNum)->curveNbr == v_y.size()) {
377  for (unsigned int i = 0; i < v_y.size(); ++i)
378  this->plot(graphNum, i, x, v_y[i]);
379  }
380  else
381  vpTRACE("error in plot vector : not the right dimension");
382 }
383 
401 vpMouseButton::vpMouseButtonType vpPlot::plot(unsigned int graphNum, unsigned int curveNum, double x, double y,
402  double z)
403 {
404  return (graphList + graphNum)->plot(I, curveNum, x, y, z);
405 }
406 
422 vpMouseButton::vpMouseButtonType vpPlot::plot(unsigned int graphNum, double x, const vpColVector &v_y,
423  const vpColVector &v_z)
424 {
426  if ((graphList + graphNum)->curveNbr == v_y.getRows() && (graphList + graphNum)->curveNbr == v_z.getRows()) {
427  for (unsigned int i = 0; i < v_y.getRows(); ++i)
428  button = this->plot(graphNum, i, x, v_y[i], v_z[i]);
429  }
430  else
431  vpTRACE("error in plot vector : not the right dimension");
432  return button;
433 }
434 
443 {
445 
446  bool blocked = false;
447  unsigned int iblocked = 0;
448  vpImagePoint iP;
449 
450  while (b != vpMouseButton::button3) {
451  if (!blocked) {
453  for (unsigned int i = 0; i < graphNbr; ++i) {
454  if (iP.inRectangle((graphList + i)->graphZone)) {
455  iblocked = i;
456  break;
457  }
458  }
459  if ((graphList + iblocked)->move(I, b)) {
460  (graphList + iblocked)->replot3D(I);
461  }
462  blocked = (graphList + iblocked)->blocked;
463  }
464  else {
465  if ((graphList + iblocked)->move(I, b)) {
466  (graphList + iblocked)->replot3D(I);
467  }
468  blocked = (graphList + iblocked)->blocked;
469  }
470  vpTime::sleepMs(20);
471  }
472 }
473 
480 void vpPlot::getPixelValue(bool block)
481 {
482  vpImagePoint iP;
483 
484  if (block)
485  vpDisplay::getClick(I, iP);
486  else
488 
489  for (unsigned int i = 0; i < graphNbr; ++i) {
490  if ((graphList + i)->getPixelValue(I, iP))
491  break;
492  }
493 }
494 
503 void vpPlot::setTitle(unsigned int graphNum, const std::string &title) { (graphList + graphNum)->setTitle(title); }
504 
513 void vpPlot::setUnitX(unsigned int graphNum, const std::string &unitx) { (graphList + graphNum)->setUnitX(unitx); }
514 
523 void vpPlot::setUnitY(unsigned int graphNum, const std::string &unity) { (graphList + graphNum)->setUnitY(unity); }
524 
533 void vpPlot::setUnitZ(unsigned int graphNum, const std::string &unitz) { (graphList + graphNum)->setUnitZ(unitz); }
534 
545 void vpPlot::setLegend(unsigned int graphNum, unsigned int curveNum, const std::string &legend)
546 {
547  (graphList + graphNum)->setLegend(curveNum, legend);
548 }
549 
558 void vpPlot::resetPointList(unsigned int graphNum)
559 {
560  for (unsigned int i = 0; i < (graphList + graphNum)->curveNbr; ++i)
561  (graphList + graphNum)->resetPointList(i);
562 }
563 
573 void vpPlot::setThickness(unsigned int graphNum, unsigned int curveNum, unsigned int thickness)
574 {
575  (graphList + graphNum)->setCurveThickness(curveNum, thickness);
576 }
577 
586 void vpPlot::setGraphThickness(unsigned int graphNum, unsigned int thickness)
587 {
588  for (unsigned int curveNum = 0; curveNum < (graphList + graphNum)->curveNbr; ++curveNum)
589  (graphList + graphNum)->setCurveThickness(curveNum, thickness);
590 }
591 
601 void vpPlot::setGridThickness(unsigned int graphNum, unsigned int thickness)
602 {
603  (graphList + graphNum)->setGridThickness(thickness);
604 }
605 
616 void vpPlot::resetPointList(unsigned int graphNum, unsigned int curveNum)
617 {
618  (graphList + graphNum)->resetPointList(curveNum);
619 }
620 
648 void vpPlot::saveData(unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix)
649 {
650  std::ofstream fichier;
651  fichier.open(dataFile.c_str());
652 
653  unsigned int ind;
654  double *p = new double[3];
655  bool end = false;
656 
657  std::vector<std::list<double>::const_iterator> vec_iter_pointListx((graphList + graphNum)->curveNbr);
658  std::vector<std::list<double>::const_iterator> vec_iter_pointListy((graphList + graphNum)->curveNbr);
659  std::vector<std::list<double>::const_iterator> vec_iter_pointListz((graphList + graphNum)->curveNbr);
660 
661  fichier << title_prefix << (graphList + graphNum)->title << std::endl;
662 
663  for (ind = 0; ind < (graphList + graphNum)->curveNbr; ++ind) {
664  vec_iter_pointListx[ind] = (graphList + graphNum)->curveList[ind].pointListx.begin();
665  vec_iter_pointListy[ind] = (graphList + graphNum)->curveList[ind].pointListy.begin();
666  vec_iter_pointListz[ind] = (graphList + graphNum)->curveList[ind].pointListz.begin();
667  // (graphList+graphNum)->curveList[ind].pointListx.front();
668  // (graphList+graphNum)->curveList[ind].pointListy.front();
669  // (graphList+graphNum)->curveList[ind].pointListz.front();
670  }
671 
672  while (end == false) {
673  end = true;
674  for (ind = 0; ind < (graphList + graphNum)->curveNbr; ++ind) {
675  // if (!(graphList+graphNum)->curveList[ind].pointListx.outside()
676  // &&
677  // !(graphList+graphNum)->curveList[ind].pointListy.outside()
678  // &&
679  // !(graphList+graphNum)->curveList[ind].pointListz.outside())
680  if ((vec_iter_pointListx[ind] != (graphList + graphNum)->curveList[ind].pointListx.end()) &&
681  (vec_iter_pointListy[ind] != (graphList + graphNum)->curveList[ind].pointListy.end()) &&
682  (vec_iter_pointListz[ind] != (graphList + graphNum)->curveList[ind].pointListz.end())) {
683  p[0] = *vec_iter_pointListx[ind];
684  p[1] = *vec_iter_pointListy[ind];
685  p[2] = *vec_iter_pointListz[ind];
686  // p[0] =
687  // (graphList+graphNum)->curveList[ind].pointListx.value();
688  // p[1] =
689  // (graphList+graphNum)->curveList[ind].pointListy.value();
690  // p[2] =
691  // (graphList+graphNum)->curveList[ind].pointListz.value();
692 
693  fichier << p[0] << "\t" << p[1] << "\t" << p[2] << "\t";
694  ++vec_iter_pointListx[ind];
695  ++vec_iter_pointListy[ind];
696  ++vec_iter_pointListz[ind];
697  // (graphList+graphNum)->curveList[ind].pointListx.next();
698  // (graphList+graphNum)->curveList[ind].pointListy.next();
699  // (graphList+graphNum)->curveList[ind].pointListz.next();
700  // if(!(graphList+graphNum)->curveList[ind].pointListx.nextOutside()
701  // &&
702  // !(graphList+graphNum)->curveList[ind].pointListy.nextOutside()
703  // &&
704  // !(graphList+graphNum)->curveList[ind].pointListz.nextOutside())
705  if ((vec_iter_pointListx[ind] != (graphList + graphNum)->curveList[ind].pointListx.end()) &&
706  (vec_iter_pointListy[ind] != (graphList + graphNum)->curveList[ind].pointListy.end()) &&
707  (vec_iter_pointListz[ind] != (graphList + graphNum)->curveList[ind].pointListz.end()))
708  end = false;
709  }
710  else {
711  // p[0] =
712  // (graphList+graphNum)->curveList[ind].pointListx.value();
713  // p[1] =
714  // (graphList+graphNum)->curveList[ind].pointListy.value();
715  // p[2] =
716  // (graphList+graphNum)->curveList[ind].pointListz.value();
717  p[0] = (graphList + graphNum)->curveList[ind].pointListx.back();
718  p[1] = (graphList + graphNum)->curveList[ind].pointListy.back();
719  p[2] = (graphList + graphNum)->curveList[ind].pointListz.back();
720  fichier << p[0] << "\t" << p[1] << "\t" << p[2] << "\t";
721  }
722  }
723  fichier << std::endl;
724  }
725 
726  delete[] p;
727  fichier.close();
728 }
729 
730 #elif !defined(VISP_BUILD_SHARED_LIBS)
731 // Work around to avoid warning: libvisp_core.a(vpPlot.cpp.o) has no symbols
732 void dummy_vpPlot() { };
733 #endif
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:339
unsigned int getRows() const
Definition: vpArray2D.h:337
Implementation of column vector and the associated operations.
Definition: vpColVector.h:163
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:152
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:101
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:128
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:128
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:128
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
static void display(const vpImage< unsigned char > &I)
static bool getPointerPosition(const vpImage< unsigned char > &I, vpImagePoint &ip)
error that can be emitted by ViSP classes.
Definition: vpException.h:59
@ dimensionError
Bad dimension.
Definition: vpException.h:83
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:82
bool inRectangle(const vpRect &rect) const
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:631
void initGraph(unsigned int graphNum, unsigned int curveNbr)
Definition: vpPlot.cpp:202
vpImage< unsigned char > I
Definition: vpPlot.h:111
void setUnitY(unsigned int graphNum, const std::string &unity)
Definition: vpPlot.cpp:523
virtual ~vpPlot()
Definition: vpPlot.cpp:125
void init(unsigned int nbGraph, unsigned int height=700, unsigned int width=700, int x=-1, int y=-1, const std::string &title="")
Definition: vpPlot.cpp:95
void initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
Definition: vpPlot.cpp:214
void setGridThickness(unsigned int graphNum, unsigned int thickness)
Definition: vpPlot.cpp:601
void setLegend(unsigned int graphNum, unsigned int curveNum, const std::string &legend)
Definition: vpPlot.cpp:545
void plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
Definition: vpPlot.cpp:269
void setUnitX(unsigned int graphNum, const std::string &unitx)
Definition: vpPlot.cpp:513
void setColor(unsigned int graphNum, unsigned int curveNum, vpColor color)
Definition: vpPlot.cpp:245
void setThickness(unsigned int graphNum, unsigned int curveNum, unsigned int thickness)
Definition: vpPlot.cpp:573
void navigate(void)
Definition: vpPlot.cpp:442
void setGraphThickness(unsigned int graphNum, unsigned int thickness)
Definition: vpPlot.cpp:586
vpPlot()
Definition: vpPlot.cpp:58
void setUnitZ(unsigned int graphNum, const std::string &unitz)
Definition: vpPlot.cpp:533
void setTitle(unsigned int graphNum, const std::string &title)
Definition: vpPlot.cpp:503
void saveData(unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix="")
Definition: vpPlot.cpp:648
void resetPointList(unsigned int graphNum)
Definition: vpPlot.cpp:558
void getPixelValue(bool block)
Definition: vpPlot.cpp:480
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:189
Implementation of a generic rotation vector.
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:107
Class that consider the case of a translation vector.
#define vpTRACE
Definition: vpDebug.h:405
VISP_EXPORT void sleepMs(double t)