Visual Servoing Platform  version 3.5.1 under development (2023-03-14)
vpPlot.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 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  * Plot curves.
33  *
34  * Authors:
35  * Nicolas Melchior
36  *
37  *****************************************************************************/
38 
39 #include <visp3/core/vpConfig.h>
40 
41 #if defined(VISP_HAVE_DISPLAY)
42 #include <fstream>
43 #include <list>
44 #include <vector>
45 #include <visp3/core/vpMath.h>
46 #include <visp3/core/vpMeterPixelConversion.h>
47 #include <visp3/core/vpPixelMeterConversion.h>
48 #include <visp3/gui/vpDisplayD3D.h>
49 #include <visp3/gui/vpDisplayGDI.h>
50 #include <visp3/gui/vpDisplayGTK.h>
51 #include <visp3/gui/vpDisplayOpenCV.h>
52 #include <visp3/gui/vpDisplayX.h>
53 #include <visp3/gui/vpPlot.h>
54 
61 vpPlot::vpPlot() : I(), display(NULL), graphNbr(1), graphList(NULL), margei(30), margej(40), factori(1.f), factorj(1.)
62 {
63 }
81 vpPlot::vpPlot(unsigned int graph_nbr, unsigned int height, unsigned int width, int x, int y, const std::string &title)
82  : I(), display(NULL), graphNbr(1), graphList(NULL), margei(30), margej(40), factori(1.f), factorj(1.)
83 {
84  init(graph_nbr, height, width, x, y, title);
85 }
86 
99 void vpPlot::init(unsigned int graph_nbr, unsigned int height, unsigned int width, int x, int y,
100  const std::string &title)
101 {
102  I.init(height, width, 255);
103 
104 #if defined VISP_HAVE_X11
105  display = new vpDisplayX;
106 #elif defined VISP_HAVE_GDI
107  display = new vpDisplayGDI;
108 #elif defined VISP_HAVE_OPENCV
109  display = new vpDisplayOpenCV;
110 #elif defined VISP_HAVE_GTK
111  display = new vpDisplayGTK;
112 #elif defined VISP_HAVE_D3D9
113  display = new vpDisplayD3D;
114 #endif
115 
116  display->init(I, x, y, title.c_str());
117 
119 
120  factori = height / 700.0f;
121  factorj = width / 700.0f;
122 
123  initNbGraph(graph_nbr);
124 }
125 
130 {
131  if (graphList != NULL) {
132  delete[] graphList;
133  graphList = NULL;
134  }
135  if (display != NULL) {
136  delete display;
137  display = NULL;
138  }
139 }
140 
150 void vpPlot::initNbGraph(unsigned int nbGraph)
151 {
152  if (nbGraph > 4) {
153  throw vpException(vpException::dimensionError, "Cannot create more than 4 graphs");
154  }
155  graphList = new vpPlotGraph[nbGraph];
156  graphNbr = nbGraph;
157 
158  switch (nbGraph) {
159  case 1:
160  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(700 * factorj), (unsigned int)(700 * factori), margei,
161  margej);
162  break;
163  case 2:
164  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(700 * factorj), (unsigned int)(350 * factori), margei,
165  margej);
166  graphList[1].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(700 * factorj),
167  (unsigned int)(350 * factori), margei, margej);
168  break;
169  case 3:
170  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei,
171  margej);
172  graphList[1].initSize(vpImagePoint(0, (unsigned int)(350 * factorj)), (unsigned int)(350 * factorj),
173  (unsigned int)(350 * factori), margei, margej);
174  graphList[2].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(700 * factorj),
175  (unsigned int)(350 * factori), margei, margej);
176  break;
177  case 4:
178  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei,
179  margej);
180  graphList[1].initSize(vpImagePoint(0, (unsigned int)(350 * factorj)), (unsigned int)(350 * factorj),
181  (unsigned int)(350 * factori), margei, margej);
182  graphList[2].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(350 * factorj),
183  (unsigned int)(350 * factori), margei, margej);
184  graphList[3].initSize(vpImagePoint((unsigned int)(350 * factori), (unsigned int)(350 * factorj)),
185  (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei, margej);
186  break;
187  }
188 
189  for (unsigned int i = 0; i < graphNbr; i++) {
190  graphList[i].title.clear();
191  graphList[i].unitx.clear();
192  graphList[i].unity.clear();
193  graphList[i].unitz.clear();
194  }
195 }
196 
205 void vpPlot::initGraph(unsigned int graphNum, unsigned int curveNbr) { (graphList + graphNum)->initGraph(curveNbr); }
206 
207 // void
208 // vpPlot::initRange (const int graphNum,
209 // double xmin, double xmax, double /*xdelt*/,
210 // double ymin, double ymax, double /*ydelt*/,
211 // bool gx, bool gy)
212 // {
213 // (graphList+graphNum)->initScale(I,xmin,xmax,10,ymin,ymax,10,gx,gy);
214 // }
215 
227 void vpPlot::initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
228 {
229  (graphList + graphNum)->initScale(I, xmin, xmax, 10, ymin, ymax, 10, true, true);
230 }
231 
246 void vpPlot::initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax, double zmin,
247  double zmax)
248 {
249  (graphList + graphNum)->initScale(I, xmin, xmax, 10, ymin, ymax, 10, zmin, zmax, 10, true, true);
250 }
251 
260 void vpPlot::setColor(unsigned int graphNum, unsigned int curveNum, vpColor color)
261 {
262  (graphList + graphNum)->setCurveColor(curveNum, color);
263 }
264 
268 void vpPlot::displayGrid()
269 {
270  for (unsigned int i = 0; i < graphNbr; i++)
271  graphList[i].displayGrid(I);
272 }
273 
285 void vpPlot::plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
286 {
287  (graphList + graphNum)->plot(I, curveNum, x, y);
288 }
289 
301 void vpPlot::plot(unsigned int graphNum, double x, const vpColVector &v_y)
302 {
303  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
304  for (unsigned int i = 0; i < v_y.getRows(); ++i)
305  this->plot(graphNum, i, x, v_y[i]);
306  } else
307  vpTRACE("error in plot vector : not the right dimension");
308 }
320 void vpPlot::plot(unsigned int graphNum, double x, const vpRowVector &v_y)
321 {
322  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
323  for (unsigned int i = 0; i < v_y.getRows(); ++i)
324  this->plot(graphNum, i, x, v_y[i]);
325  } else
326  vpTRACE("error in plot vector : not the right dimension");
327 }
328 
340 void vpPlot::plot(unsigned int graphNum, double x, const vpPoseVector &v_y)
341 {
342  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
343  for (unsigned int i = 0; i < v_y.getRows(); ++i)
344  this->plot(graphNum, i, x, v_y[i]);
345  } else
346  vpTRACE("error in plot vector : not the right dimension");
347 }
359 void vpPlot::plot(unsigned int graphNum, double x, const vpTranslationVector &v_y)
360 {
361  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
362  for (unsigned int i = 0; i < v_y.getRows(); ++i)
363  this->plot(graphNum, i, x, v_y[i]);
364  } else
365  vpTRACE("error in plot vector : not the right dimension");
366 }
367 
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  } else
385  vpTRACE("error in plot vector : not the right dimension");
386 }
387 
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 
419 vpMouseButton::vpMouseButtonType vpPlot::plot(unsigned int graphNum, double x, const vpColVector &v_y,
420  const vpColVector &v_z)
421 {
423  if ((graphList + graphNum)->curveNbr == v_y.getRows() && (graphList + graphNum)->curveNbr == v_z.getRows()) {
424  for (unsigned int i = 0; i < v_y.getRows(); ++i)
425  button = this->plot(graphNum, i, x, v_y[i], v_z[i]);
426  } else
427  vpTRACE("error in plot vector : not the right dimension");
428  return button;
429 }
430 
439 {
441 
442  bool blocked = false;
443  unsigned int iblocked = 0;
444  vpImagePoint iP;
445 
446  while (b != vpMouseButton::button3) {
447  if (!blocked) {
449  for (unsigned int i = 0; i < graphNbr; i++) {
450  if (iP.inRectangle((graphList + i)->graphZone)) {
451  iblocked = i;
452  break;
453  }
454  }
455  if ((graphList + iblocked)->move(I, b)) {
456  (graphList + iblocked)->replot3D(I);
457  }
458  blocked = (graphList + iblocked)->blocked;
459  } else {
460  if ((graphList + iblocked)->move(I, b)) {
461  (graphList + iblocked)->replot3D(I);
462  }
463  blocked = (graphList + iblocked)->blocked;
464  }
465  vpTime::sleepMs(20);
466  }
467 }
468 
475 void vpPlot::getPixelValue(bool block)
476 {
477  vpImagePoint iP;
478 
479  if (block)
480  vpDisplay::getClick(I, iP);
481  else
483 
484  for (unsigned int i = 0; i < graphNbr; i++) {
485  if ((graphList + i)->getPixelValue(I, iP))
486  break;
487  }
488 }
489 
497 void vpPlot::setTitle(unsigned int graphNum, const std::string &title) { (graphList + graphNum)->setTitle(title); }
498 
506 void vpPlot::setUnitX(unsigned int graphNum, const std::string &unitx) { (graphList + graphNum)->setUnitX(unitx); }
507 
515 void vpPlot::setUnitY(unsigned int graphNum, const std::string &unity) { (graphList + graphNum)->setUnitY(unity); }
516 
524 void vpPlot::setUnitZ(unsigned int graphNum, const std::string &unitz) { (graphList + graphNum)->setUnitZ(unitz); }
525 
534 void vpPlot::setLegend(unsigned int graphNum, unsigned int curveNum, const std::string &legend)
535 {
536  (graphList + graphNum)->setLegend(curveNum, legend);
537 }
538 
547 void vpPlot::resetPointList(unsigned int graphNum)
548 {
549  for (unsigned int i = 0; i < (graphList + graphNum)->curveNbr; i++)
550  (graphList + graphNum)->resetPointList(i);
551 }
552 
561 void vpPlot::setThickness(unsigned int graphNum, unsigned int curveNum, unsigned int thickness)
562 {
563  (graphList + graphNum)->setCurveThickness(curveNum, thickness);
564 }
565 
574 void vpPlot::setGraphThickness(unsigned int graphNum, unsigned int thickness)
575 {
576  for (unsigned int curveNum = 0; curveNum < (graphList + graphNum)->curveNbr; curveNum++)
577  (graphList + graphNum)->setCurveThickness(curveNum, thickness);
578 }
579 
588 void vpPlot::setGridThickness(unsigned int graphNum, unsigned int thickness)
589 {
590  (graphList + graphNum)->setGridThickness(thickness);
591 }
592 
602 void vpPlot::resetPointList(unsigned int graphNum, unsigned int curveNum)
603 {
604  (graphList + graphNum)->resetPointList(curveNum);
605 }
606 
633 void vpPlot::saveData(unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix)
634 {
635  std::ofstream fichier;
636  fichier.open(dataFile.c_str());
637 
638  unsigned int ind;
639  double *p = new double[3];
640  bool end = false;
641 
642  std::vector<std::list<double>::const_iterator> vec_iter_pointListx((graphList + graphNum)->curveNbr);
643  std::vector<std::list<double>::const_iterator> vec_iter_pointListy((graphList + graphNum)->curveNbr);
644  std::vector<std::list<double>::const_iterator> vec_iter_pointListz((graphList + graphNum)->curveNbr);
645 
646  fichier << title_prefix << (graphList + graphNum)->title << std::endl;
647 
648  for (ind = 0; ind < (graphList + graphNum)->curveNbr; ind++) {
649  vec_iter_pointListx[ind] = (graphList + graphNum)->curveList[ind].pointListx.begin();
650  vec_iter_pointListy[ind] = (graphList + graphNum)->curveList[ind].pointListy.begin();
651  vec_iter_pointListz[ind] = (graphList + graphNum)->curveList[ind].pointListz.begin();
652  // (graphList+graphNum)->curveList[ind].pointListx.front();
653  // (graphList+graphNum)->curveList[ind].pointListy.front();
654  // (graphList+graphNum)->curveList[ind].pointListz.front();
655  }
656 
657  while (end == false) {
658  end = true;
659  for (ind = 0; ind < (graphList + graphNum)->curveNbr; ind++) {
660  // if (!(graphList+graphNum)->curveList[ind].pointListx.outside()
661  // &&
662  // !(graphList+graphNum)->curveList[ind].pointListy.outside()
663  // &&
664  // !(graphList+graphNum)->curveList[ind].pointListz.outside())
665  if ((vec_iter_pointListx[ind] != (graphList + graphNum)->curveList[ind].pointListx.end()) &&
666  (vec_iter_pointListy[ind] != (graphList + graphNum)->curveList[ind].pointListy.end()) &&
667  (vec_iter_pointListz[ind] != (graphList + graphNum)->curveList[ind].pointListz.end())) {
668  p[0] = *vec_iter_pointListx[ind];
669  p[1] = *vec_iter_pointListy[ind];
670  p[2] = *vec_iter_pointListz[ind];
671  // p[0] =
672  // (graphList+graphNum)->curveList[ind].pointListx.value();
673  // p[1] =
674  // (graphList+graphNum)->curveList[ind].pointListy.value();
675  // p[2] =
676  // (graphList+graphNum)->curveList[ind].pointListz.value();
677 
678  fichier << p[0] << "\t" << p[1] << "\t" << p[2] << "\t";
679  ++vec_iter_pointListx[ind];
680  ++vec_iter_pointListy[ind];
681  ++vec_iter_pointListz[ind];
682  // (graphList+graphNum)->curveList[ind].pointListx.next();
683  // (graphList+graphNum)->curveList[ind].pointListy.next();
684  // (graphList+graphNum)->curveList[ind].pointListz.next();
685  // if(!(graphList+graphNum)->curveList[ind].pointListx.nextOutside()
686  // &&
687  // !(graphList+graphNum)->curveList[ind].pointListy.nextOutside()
688  // &&
689  // !(graphList+graphNum)->curveList[ind].pointListz.nextOutside())
690  if ((vec_iter_pointListx[ind] != (graphList + graphNum)->curveList[ind].pointListx.end()) &&
691  (vec_iter_pointListy[ind] != (graphList + graphNum)->curveList[ind].pointListy.end()) &&
692  (vec_iter_pointListz[ind] != (graphList + graphNum)->curveList[ind].pointListz.end()))
693  end = false;
694  } else {
695  // p[0] =
696  // (graphList+graphNum)->curveList[ind].pointListx.value();
697  // p[1] =
698  // (graphList+graphNum)->curveList[ind].pointListy.value();
699  // p[2] =
700  // (graphList+graphNum)->curveList[ind].pointListz.value();
701  p[0] = (graphList + graphNum)->curveList[ind].pointListx.back();
702  p[1] = (graphList + graphNum)->curveList[ind].pointListy.back();
703  p[2] = (graphList + graphNum)->curveList[ind].pointListz.back();
704  fichier << p[0] << "\t" << p[1] << "\t" << p[2] << "\t";
705  }
706  }
707  fichier << std::endl;
708  }
709 
710  delete[] p;
711  fichier.close();
712 }
713 
714 #elif !defined(VISP_BUILD_SHARED_LIBS)
715 // Work around to avoid warning: libvisp_core.a(vpPlot.cpp.o) has no symbols
716 void dummy_vpPlot(){};
717 #endif
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:290
unsigned int getRows() const
Definition: vpArray2D.h:288
Implementation of column vector and the associated operations.
Definition: vpColVector.h:131
Class to define RGB colors available for display functionnalities.
Definition: vpColor.h:158
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed....
Definition: vpDisplayD3D.h:107
Display for windows using GDI (available on any windows 32 platform).
Definition: vpDisplayGDI.h:129
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:135
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 emited by ViSP classes.
Definition: vpException.h:72
@ dimensionError
Bad dimension.
Definition: vpException.h:95
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:89
bool inRectangle(const vpRect &rect) const
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:644
void initGraph(unsigned int graphNum, unsigned int curveNbr)
Definition: vpPlot.cpp:205
vpImage< unsigned char > I
Definition: vpPlot.h:118
void setUnitY(unsigned int graphNum, const std::string &unity)
Definition: vpPlot.cpp:515
virtual ~vpPlot()
Definition: vpPlot.cpp:129
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:99
void initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
Definition: vpPlot.cpp:227
void setGridThickness(unsigned int graphNum, unsigned int thickness)
Definition: vpPlot.cpp:588
void setLegend(unsigned int graphNum, unsigned int curveNum, const std::string &legend)
Definition: vpPlot.cpp:534
void plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
Definition: vpPlot.cpp:285
void setUnitX(unsigned int graphNum, const std::string &unitx)
Definition: vpPlot.cpp:506
void setColor(unsigned int graphNum, unsigned int curveNum, vpColor color)
Definition: vpPlot.cpp:260
void setThickness(unsigned int graphNum, unsigned int curveNum, unsigned int thickness)
Definition: vpPlot.cpp:561
void navigate(void)
Definition: vpPlot.cpp:438
void setGraphThickness(unsigned int graphNum, unsigned int thickness)
Definition: vpPlot.cpp:574
vpPlot()
Definition: vpPlot.cpp:61
void setUnitZ(unsigned int graphNum, const std::string &unitz)
Definition: vpPlot.cpp:524
void setTitle(unsigned int graphNum, const std::string &title)
Definition: vpPlot.cpp:497
void saveData(unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix="")
Definition: vpPlot.cpp:633
void resetPointList(unsigned int graphNum)
Definition: vpPlot.cpp:547
void getPixelValue(bool block)
Definition: vpPlot.cpp:475
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:152
Implementation of a generic rotation vector.
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:116
Class that consider the case of a translation vector.
#define vpTRACE
Definition: vpDebug.h:416
VISP_EXPORT void sleepMs(double t)