Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
vpPlot.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  * Plot curves.
32  *
33 *****************************************************************************/
34 
35 #include <visp3/core/vpConfig.h>
36 
37 #if defined(VISP_HAVE_DISPLAY)
38 #include <fstream>
39 #include <list>
40 #include <vector>
41 #include <visp3/core/vpMath.h>
42 #include <visp3/core/vpMeterPixelConversion.h>
43 #include <visp3/core/vpPixelMeterConversion.h>
44 #include <visp3/gui/vpDisplayD3D.h>
45 #include <visp3/gui/vpDisplayGDI.h>
46 #include <visp3/gui/vpDisplayGTK.h>
47 #include <visp3/gui/vpDisplayOpenCV.h>
48 #include <visp3/gui/vpDisplayX.h>
49 #include <visp3/gui/vpPlot.h>
50 
52 
59 vpPlot::vpPlot() : I(), display(nullptr), graphNbr(1), graphList(nullptr), margei(30), margej(40), factori(1.f), factorj(1.)
60 { }
78 vpPlot::vpPlot(unsigned int graph_nbr, unsigned int height, unsigned int width, int x, int y, const std::string &title)
79  : I(), display(nullptr), graphNbr(1), graphList(nullptr), margei(30), margej(40), factori(1.f), factorj(1.)
80 {
81  init(graph_nbr, height, width, x, y, title);
82 }
83 
96 void vpPlot::init(unsigned int graph_nbr, unsigned int height, unsigned int width, int x, int y,
97  const std::string &title)
98 {
99  I.init(height, width, 255);
100 
101 #if defined(VISP_HAVE_X11)
102  display = new vpDisplayX;
103 #elif defined(VISP_HAVE_GDI)
104  display = new vpDisplayGDI;
105 #elif defined(HAVE_OPENCV_HIGHGUI)
106  display = new vpDisplayOpenCV;
107 #elif defined(VISP_HAVE_GTK)
108  display = new vpDisplayGTK;
109 #elif defined(VISP_HAVE_D3D9)
110  display = new vpDisplayD3D;
111 #endif
112 
113  display->init(I, x, y, title);
114 
116 
117  factori = height / 700.0f;
118  factorj = width / 700.0f;
119 
120  initNbGraph(graph_nbr);
121 }
122 
127 {
128  if (graphList != nullptr) {
129  delete[] graphList;
130  graphList = nullptr;
131  }
132  if (display != nullptr) {
133  delete display;
134  display = nullptr;
135  }
136 }
137 
147 void vpPlot::initNbGraph(unsigned int nbGraph)
148 {
149  if (nbGraph > 4) {
150  throw vpException(vpException::dimensionError, "Cannot create more than 4 graphs");
151  }
152  graphList = new vpPlotGraph[nbGraph];
153  graphNbr = nbGraph;
154 
155  switch (nbGraph) {
156  case 1:
157  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(700 * factorj), (unsigned int)(700 * factori), margei,
158  margej);
159  break;
160  case 2:
161  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(700 * factorj), (unsigned int)(350 * factori), margei,
162  margej);
163  graphList[1].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(700 * factorj),
164  (unsigned int)(350 * factori), margei, margej);
165  break;
166  case 3:
167  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei,
168  margej);
169  graphList[1].initSize(vpImagePoint(0, (unsigned int)(350 * factorj)), (unsigned int)(350 * factorj),
170  (unsigned int)(350 * factori), margei, margej);
171  graphList[2].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(700 * factorj),
172  (unsigned int)(350 * factori), margei, margej);
173  break;
174  case 4:
175  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei,
176  margej);
177  graphList[1].initSize(vpImagePoint(0, (unsigned int)(350 * factorj)), (unsigned int)(350 * factorj),
178  (unsigned int)(350 * factori), margei, margej);
179  graphList[2].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(350 * factorj),
180  (unsigned int)(350 * factori), margei, margej);
181  graphList[3].initSize(vpImagePoint((unsigned int)(350 * factori), (unsigned int)(350 * factorj)),
182  (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei, margej);
183  break;
184  }
185 
186  for (unsigned int i = 0; i < graphNbr; ++i) {
187  graphList[i].title.clear();
188  graphList[i].unitx.clear();
189  graphList[i].unity.clear();
190  graphList[i].unitz.clear();
191  }
192 }
193 
203 void vpPlot::initGraph(unsigned int graphNum, unsigned int curveNbr) { (graphList + graphNum)->initGraph(curveNbr); }
204 
215 void vpPlot::initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
216 {
217  (graphList + graphNum)->initScale(I, xmin, xmax, 10, ymin, ymax, 10, true, true);
218 }
219 
232 void vpPlot::initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax, double zmin,
233  double zmax)
234 {
235  (graphList + graphNum)->initScale(I, xmin, xmax, 10, ymin, ymax, 10, zmin, zmax, 10, true, true);
236 }
237 
246 void vpPlot::setColor(unsigned int graphNum, unsigned int curveNum, vpColor color)
247 {
248  (graphList + graphNum)->setCurveColor(curveNum, color);
249 }
250 
254 void vpPlot::displayGrid()
255 {
256  for (unsigned int i = 0; i < graphNbr; ++i)
257  graphList[i].displayGrid(I);
258 }
259 
270 void vpPlot::plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
271 {
272  (graphList + graphNum)->plot(I, curveNum, x, y);
273 }
274 
286 void vpPlot::plot(unsigned int graphNum, double x, const vpColVector &v_y)
287 {
288  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
289  for (unsigned int i = 0; i < v_y.getRows(); ++i)
290  this->plot(graphNum, i, x, v_y[i]);
291  }
292  else {
293  throw(vpException(vpException::dimensionError, "Error in plot vector: not the right dimension"));
294  }
295 }
308 void vpPlot::plot(unsigned int graphNum, double x, const vpRowVector &v_y)
309 {
310  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
311  for (unsigned int i = 0; i < v_y.getRows(); ++i)
312  this->plot(graphNum, i, x, v_y[i]);
313  }
314  else {
315  throw(vpException(vpException::dimensionError, "Error in plot vector: not the right dimension"));
316  }
317 }
318 
332 void vpPlot::plot(unsigned int graphNum, double x, const vpPoseVector &v_y)
333 {
334  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
335  for (unsigned int i = 0; i < v_y.getRows(); ++i)
336  this->plot(graphNum, i, x, v_y[i]);
337  }
338  else {
339  throw(vpException(vpException::dimensionError, "Error in plot vector: not the right dimension"));
340  }
341 }
355 void vpPlot::plot(unsigned int graphNum, double x, const vpTranslationVector &v_y)
356 {
357  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
358  for (unsigned int i = 0; i < v_y.getRows(); ++i)
359  this->plot(graphNum, i, x, v_y[i]);
360  }
361  else {
362  throw(vpException(vpException::dimensionError, "Error in plot vector: not the right dimension"));
363  }
364 }
365 
379 void vpPlot::plot(unsigned int graphNum, double x, const vpRotationVector &v_y)
380 {
381  if ((graphList + graphNum)->curveNbr == v_y.size()) {
382  for (unsigned int i = 0; i < v_y.size(); ++i)
383  this->plot(graphNum, i, x, v_y[i]);
384  }
385  else {
386  throw(vpException(vpException::dimensionError, "Error in plot vector: not the right dimension"));
387  }
388 }
389 
407 vpMouseButton::vpMouseButtonType vpPlot::plot(unsigned int graphNum, unsigned int curveNum, double x, double y,
408  double z)
409 {
410  return (graphList + graphNum)->plot(I, curveNum, x, y, z);
411 }
412 
428 vpMouseButton::vpMouseButtonType vpPlot::plot(unsigned int graphNum, double x, const vpColVector &v_y,
429  const vpColVector &v_z)
430 {
432  if ((graphList + graphNum)->curveNbr == v_y.getRows() && (graphList + graphNum)->curveNbr == v_z.getRows()) {
433  for (unsigned int i = 0; i < v_y.getRows(); ++i)
434  button = this->plot(graphNum, i, x, v_y[i], v_z[i]);
435  }
436  else {
437  throw(vpException(vpException::dimensionError, "Error in plot vector: not the right dimension"));
438  }
439  return button;
440 }
441 
450 {
452 
453  bool blocked = false;
454  unsigned int iblocked = 0;
455  vpImagePoint iP;
456 
457  while (b != vpMouseButton::button3) {
458  if (!blocked) {
460  for (unsigned int i = 0; i < graphNbr; ++i) {
461  if (iP.inRectangle((graphList + i)->graphZone)) {
462  iblocked = i;
463  break;
464  }
465  }
466  if ((graphList + iblocked)->move(I, b)) {
467  (graphList + iblocked)->replot3D(I);
468  }
469  blocked = (graphList + iblocked)->blocked;
470  }
471  else {
472  if ((graphList + iblocked)->move(I, b)) {
473  (graphList + iblocked)->replot3D(I);
474  }
475  blocked = (graphList + iblocked)->blocked;
476  }
477  vpTime::sleepMs(20);
478  }
479 }
480 
487 void vpPlot::getPixelValue(bool block)
488 {
489  vpImagePoint iP;
490 
491  if (block)
492  vpDisplay::getClick(I, iP);
493  else
495 
496  for (unsigned int i = 0; i < graphNbr; ++i) {
497  if ((graphList + i)->getPixelValue(I, iP))
498  break;
499  }
500 }
501 
510 void vpPlot::setTitle(unsigned int graphNum, const std::string &title) { (graphList + graphNum)->setTitle(title); }
511 
520 void vpPlot::setUnitX(unsigned int graphNum, const std::string &unitx) { (graphList + graphNum)->setUnitX(unitx); }
521 
530 void vpPlot::setUnitY(unsigned int graphNum, const std::string &unity) { (graphList + graphNum)->setUnitY(unity); }
531 
540 void vpPlot::setUnitZ(unsigned int graphNum, const std::string &unitz) { (graphList + graphNum)->setUnitZ(unitz); }
541 
552 void vpPlot::setLegend(unsigned int graphNum, unsigned int curveNum, const std::string &legend)
553 {
554  (graphList + graphNum)->setLegend(curveNum, legend);
555 }
556 
565 void vpPlot::resetPointList(unsigned int graphNum)
566 {
567  for (unsigned int i = 0; i < (graphList + graphNum)->curveNbr; ++i)
568  (graphList + graphNum)->resetPointList(i);
569 }
570 
580 void vpPlot::setThickness(unsigned int graphNum, unsigned int curveNum, unsigned int thickness)
581 {
582  (graphList + graphNum)->setCurveThickness(curveNum, thickness);
583 }
584 
593 void vpPlot::setGraphThickness(unsigned int graphNum, unsigned int thickness)
594 {
595  for (unsigned int curveNum = 0; curveNum < (graphList + graphNum)->curveNbr; ++curveNum)
596  (graphList + graphNum)->setCurveThickness(curveNum, thickness);
597 }
598 
608 void vpPlot::setGridThickness(unsigned int graphNum, unsigned int thickness)
609 {
610  (graphList + graphNum)->setGridThickness(thickness);
611 }
612 
623 void vpPlot::resetPointList(unsigned int graphNum, unsigned int curveNum)
624 {
625  (graphList + graphNum)->resetPointList(curveNum);
626 }
627 
655 void vpPlot::saveData(unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix)
656 {
657  std::ofstream fichier;
658  fichier.open(dataFile.c_str());
659 
660  unsigned int ind;
661  double *p = new double[3];
662  bool end = false;
663 
664  std::vector<std::list<double>::const_iterator> vec_iter_pointListx((graphList + graphNum)->curveNbr);
665  std::vector<std::list<double>::const_iterator> vec_iter_pointListy((graphList + graphNum)->curveNbr);
666  std::vector<std::list<double>::const_iterator> vec_iter_pointListz((graphList + graphNum)->curveNbr);
667 
668  fichier << title_prefix << (graphList + graphNum)->title << std::endl;
669 
670  for (ind = 0; ind < (graphList + graphNum)->curveNbr; ++ind) {
671  vec_iter_pointListx[ind] = (graphList + graphNum)->curveList[ind].pointListx.begin();
672  vec_iter_pointListy[ind] = (graphList + graphNum)->curveList[ind].pointListy.begin();
673  vec_iter_pointListz[ind] = (graphList + graphNum)->curveList[ind].pointListz.begin();
674  // (graphList+graphNum)->curveList[ind].pointListx.front();
675  // (graphList+graphNum)->curveList[ind].pointListy.front();
676  // (graphList+graphNum)->curveList[ind].pointListz.front();
677  }
678 
679  while (end == false) {
680  end = true;
681  for (ind = 0; ind < (graphList + graphNum)->curveNbr; ++ind) {
682  // if (!(graphList+graphNum)->curveList[ind].pointListx.outside()
683  // &&
684  // !(graphList+graphNum)->curveList[ind].pointListy.outside()
685  // &&
686  // !(graphList+graphNum)->curveList[ind].pointListz.outside())
687  if ((vec_iter_pointListx[ind] != (graphList + graphNum)->curveList[ind].pointListx.end()) &&
688  (vec_iter_pointListy[ind] != (graphList + graphNum)->curveList[ind].pointListy.end()) &&
689  (vec_iter_pointListz[ind] != (graphList + graphNum)->curveList[ind].pointListz.end())) {
690  p[0] = *vec_iter_pointListx[ind];
691  p[1] = *vec_iter_pointListy[ind];
692  p[2] = *vec_iter_pointListz[ind];
693  // p[0] =
694  // (graphList+graphNum)->curveList[ind].pointListx.value();
695  // p[1] =
696  // (graphList+graphNum)->curveList[ind].pointListy.value();
697  // p[2] =
698  // (graphList+graphNum)->curveList[ind].pointListz.value();
699 
700  fichier << p[0] << "\t" << p[1] << "\t" << p[2] << "\t";
701  ++vec_iter_pointListx[ind];
702  ++vec_iter_pointListy[ind];
703  ++vec_iter_pointListz[ind];
704  // (graphList+graphNum)->curveList[ind].pointListx.next();
705  // (graphList+graphNum)->curveList[ind].pointListy.next();
706  // (graphList+graphNum)->curveList[ind].pointListz.next();
707  // if(!(graphList+graphNum)->curveList[ind].pointListx.nextOutside()
708  // &&
709  // !(graphList+graphNum)->curveList[ind].pointListy.nextOutside()
710  // &&
711  // !(graphList+graphNum)->curveList[ind].pointListz.nextOutside())
712  if ((vec_iter_pointListx[ind] != (graphList + graphNum)->curveList[ind].pointListx.end()) &&
713  (vec_iter_pointListy[ind] != (graphList + graphNum)->curveList[ind].pointListy.end()) &&
714  (vec_iter_pointListz[ind] != (graphList + graphNum)->curveList[ind].pointListz.end()))
715  end = false;
716  }
717  else {
718  // p[0] =
719  // (graphList+graphNum)->curveList[ind].pointListx.value();
720  // p[1] =
721  // (graphList+graphNum)->curveList[ind].pointListy.value();
722  // p[2] =
723  // (graphList+graphNum)->curveList[ind].pointListz.value();
724  p[0] = (graphList + graphNum)->curveList[ind].pointListx.back();
725  p[1] = (graphList + graphNum)->curveList[ind].pointListy.back();
726  p[2] = (graphList + graphNum)->curveList[ind].pointListz.back();
727  fichier << p[0] << "\t" << p[1] << "\t" << p[2] << "\t";
728  }
729  }
730  fichier << std::endl;
731  }
732 
733  delete[] p;
734  fichier.close();
735 }
736 
737 END_VISP_NAMESPACE
738 
739 #elif !defined(VISP_BUILD_SHARED_LIBS)
740 // Work around to avoid warning: libvisp_gui.a(vpPlot.cpp.o) has no symbols
741 void dummy_vpPlot() { };
742 #endif
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:349
unsigned int getRows() const
Definition: vpArray2D.h:347
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
Class to define RGB colors available for display functionalities.
Definition: vpColor.h:157
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:106
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:130
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:133
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:135
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:60
@ dimensionError
Bad dimension.
Definition: vpException.h:71
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:381
void initGraph(unsigned int graphNum, unsigned int curveNbr)
Definition: vpPlot.cpp:203
vpImage< unsigned char > I
Definition: vpPlot.h:114
void setUnitY(unsigned int graphNum, const std::string &unity)
Definition: vpPlot.cpp:530
vpPlot()
Definition: vpPlot.cpp:59
virtual ~vpPlot()
Definition: vpPlot.cpp:126
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:96
void initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
Definition: vpPlot.cpp:215
void setGridThickness(unsigned int graphNum, unsigned int thickness)
Definition: vpPlot.cpp:608
void setLegend(unsigned int graphNum, unsigned int curveNum, const std::string &legend)
Definition: vpPlot.cpp:552
void plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
Definition: vpPlot.cpp:270
void setUnitX(unsigned int graphNum, const std::string &unitx)
Definition: vpPlot.cpp:520
void setColor(unsigned int graphNum, unsigned int curveNum, vpColor color)
Definition: vpPlot.cpp:246
void setThickness(unsigned int graphNum, unsigned int curveNum, unsigned int thickness)
Definition: vpPlot.cpp:580
void navigate(void)
Definition: vpPlot.cpp:449
void setGraphThickness(unsigned int graphNum, unsigned int thickness)
Definition: vpPlot.cpp:593
void setUnitZ(unsigned int graphNum, const std::string &unitz)
Definition: vpPlot.cpp:540
void setTitle(unsigned int graphNum, const std::string &title)
Definition: vpPlot.cpp:510
void saveData(unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix="")
Definition: vpPlot.cpp:655
void resetPointList(unsigned int graphNum)
Definition: vpPlot.cpp:565
void getPixelValue(bool block)
Definition: vpPlot.cpp:487
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:203
Implementation of a generic rotation vector.
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:124
Class that consider the case of a translation vector.
VISP_EXPORT void sleepMs(double t)