Visual Servoing Platform  version 3.2.1 under development (2019-05-20)
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(const unsigned int graph_nbr, const unsigned int height, const unsigned int width, const int x,
82  const int y, const std::string &title)
83  : I(), display(NULL), graphNbr(1), graphList(NULL), margei(30), margej(40), factori(1.f), factorj(1.)
84 {
85  init(graph_nbr, height, width, x, y, title);
86 }
87 
100 void vpPlot::init(const unsigned int graph_nbr, const unsigned int height, const unsigned int width, const int x,
101  const int y, const std::string &title)
102 {
103  I.init(height, width, 255);
104 
105 #if defined VISP_HAVE_X11
106  display = new vpDisplayX;
107 #elif defined VISP_HAVE_GDI
108  display = new vpDisplayGDI;
109 #elif defined VISP_HAVE_OPENCV
110  display = new vpDisplayOpenCV;
111 #elif defined VISP_HAVE_GTK
112  display = new vpDisplayGTK;
113 #elif defined VISP_HAVE_D3D9
114  display = new vpDisplayD3D;
115 #endif
116 
117  display->init(I, x, y, title.c_str());
118 
120 
121  factori = height / 700.0f;
122  factorj = width / 700.0f;
123 
124  initNbGraph(graph_nbr);
125 }
126 
131 {
132  if (graphList != NULL) {
133  delete[] graphList;
134  graphList = NULL;
135  }
136  if (display != NULL) {
137  delete display;
138  display = NULL;
139  }
140 }
141 
151 void vpPlot::initNbGraph(unsigned int nbGraph)
152 {
153  if (nbGraph > 4) {
154  throw vpException(vpException::dimensionError, "Cannot create more than 4 graphs");
155  }
156  graphList = new vpPlotGraph[nbGraph];
157  graphNbr = nbGraph;
158 
159  switch (nbGraph) {
160  case 1:
161  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(700 * factorj), (unsigned int)(700 * factori), margei,
162  margej);
163  break;
164  case 2:
165  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(700 * factorj), (unsigned int)(350 * factori), margei,
166  margej);
167  graphList[1].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(700 * factorj),
168  (unsigned int)(350 * factori), margei, margej);
169  break;
170  case 3:
171  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei,
172  margej);
173  graphList[1].initSize(vpImagePoint(0, (unsigned int)(350 * factorj)), (unsigned int)(350 * factorj),
174  (unsigned int)(350 * factori), margei, margej);
175  graphList[2].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(700 * factorj),
176  (unsigned int)(350 * factori), margei, margej);
177  break;
178  case 4:
179  graphList[0].initSize(vpImagePoint(0, 0), (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei,
180  margej);
181  graphList[1].initSize(vpImagePoint(0, (unsigned int)(350 * factorj)), (unsigned int)(350 * factorj),
182  (unsigned int)(350 * factori), margei, margej);
183  graphList[2].initSize(vpImagePoint((unsigned int)(350 * factori), 0), (unsigned int)(350 * factorj),
184  (unsigned int)(350 * factori), margei, margej);
185  graphList[3].initSize(vpImagePoint((unsigned int)(350 * factori), (unsigned int)(350 * factorj)),
186  (unsigned int)(350 * factorj), (unsigned int)(350 * factori), margei, margej);
187  break;
188  }
189 
190  for (unsigned int i = 0; i < graphNbr; i++) {
191  graphList[i].title.clear();
192  graphList[i].unitx.clear();
193  graphList[i].unity.clear();
194  graphList[i].unitz.clear();
195  }
196 }
197 
206 void vpPlot::initGraph(unsigned int graphNum, unsigned int curveNbr) { (graphList + graphNum)->initGraph(curveNbr); }
207 
208 // void
209 // vpPlot::initRange (const int graphNum,
210 // double xmin, double xmax, double /*xdelt*/,
211 // double ymin, double ymax, double /*ydelt*/,
212 // const bool gx, const bool gy)
213 // {
214 // (graphList+graphNum)->initScale(I,xmin,xmax,10,ymin,ymax,10,gx,gy);
215 // }
216 
228 void vpPlot::initRange(const unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
229 {
230  (graphList + graphNum)->initScale(I, xmin, xmax, 10, ymin, ymax, 10, true, true);
231 }
232 
247 void vpPlot::initRange(const unsigned int graphNum, double xmin, double xmax, double ymin, double ymax, double zmin,
248  double zmax)
249 {
250  (graphList + graphNum)->initScale(I, xmin, xmax, 10, ymin, ymax, 10, zmin, zmax, 10, true, true);
251 }
252 
261 void vpPlot::setColor(const unsigned int graphNum, const unsigned int curveNum, vpColor color)
262 {
263  (graphList + graphNum)->setCurveColor(curveNum, color);
264 }
265 
269 void vpPlot::displayGrid()
270 {
271  for (unsigned int i = 0; i < graphNbr; i++)
272  graphList[i].displayGrid(I);
273 }
274 
286 void vpPlot::plot(const unsigned int graphNum, const unsigned int curveNum, const double x, const double y)
287 {
288  (graphList + graphNum)->plot(I, curveNum, x, y);
289 }
290 
302 void vpPlot::plot(const unsigned int graphNum, const double x, const vpColVector &v_y)
303 {
304  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
305  for (unsigned int i = 0; i < v_y.getRows(); ++i)
306  this->plot(graphNum, i, x, v_y[i]);
307  } else
308  vpTRACE("error in plot vector : not the right dimension");
309 }
321 void vpPlot::plot(const unsigned int graphNum, const double x, const vpRowVector &v_y)
322 {
323  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
324  for (unsigned int i = 0; i < v_y.getRows(); ++i)
325  this->plot(graphNum, i, x, v_y[i]);
326  } else
327  vpTRACE("error in plot vector : not the right dimension");
328 }
329 
341 void vpPlot::plot(const unsigned int graphNum, const double x, const vpPoseVector &v_y)
342 {
343  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
344  for (unsigned int i = 0; i < v_y.getRows(); ++i)
345  this->plot(graphNum, i, x, v_y[i]);
346  } else
347  vpTRACE("error in plot vector : not the right dimension");
348 }
360 void vpPlot::plot(const unsigned int graphNum, const double x, const vpTranslationVector &v_y)
361 {
362  if ((graphList + graphNum)->curveNbr == v_y.getRows()) {
363  for (unsigned int i = 0; i < v_y.getRows(); ++i)
364  this->plot(graphNum, i, x, v_y[i]);
365  } else
366  vpTRACE("error in plot vector : not the right dimension");
367 }
368 
380 void vpPlot::plot(const unsigned int graphNum, const double x, const vpRotationVector &v_y)
381 {
382  if ((graphList + graphNum)->curveNbr == v_y.size()) {
383  for (unsigned int i = 0; i < v_y.size(); ++i)
384  this->plot(graphNum, i, x, v_y[i]);
385  } else
386  vpTRACE("error in plot vector : not the right dimension");
387 }
388 
402 vpMouseButton::vpMouseButtonType vpPlot::plot(const unsigned int graphNum, const unsigned int curveNum, const double x,
403  const double y, const double z)
404 {
405  return (graphList + graphNum)->plot(I, curveNum, x, y, z);
406 }
407 
420 vpMouseButton::vpMouseButtonType vpPlot::plot(const unsigned int graphNum, const double x, const vpColVector &v_y,
421  const vpColVector &v_z)
422 {
424  if ((graphList + graphNum)->curveNbr == v_y.getRows() && (graphList + graphNum)->curveNbr == v_z.getRows()) {
425  for (unsigned int i = 0; i < v_y.getRows(); ++i)
426  button = this->plot(graphNum, i, x, v_y[i], v_z[i]);
427  } else
428  vpTRACE("error in plot vector : not the right dimension");
429  return button;
430 }
431 
440 {
442 
443  bool blocked = false;
444  unsigned int iblocked = 0;
445  vpImagePoint iP;
446 
447  while (b != vpMouseButton::button3) {
448  if (!blocked) {
450  for (unsigned int i = 0; i < graphNbr; i++) {
451  if (iP.inRectangle((graphList + i)->graphZone)) {
452  iblocked = i;
453  break;
454  }
455  }
456  if ((graphList + iblocked)->move(I, b)) {
457  (graphList + iblocked)->replot3D(I);
458  }
459  blocked = (graphList + iblocked)->blocked;
460  } else {
461  if ((graphList + iblocked)->move(I, b)) {
462  (graphList + iblocked)->replot3D(I);
463  }
464  blocked = (graphList + iblocked)->blocked;
465  }
466  vpTime::sleepMs(20);
467  }
468 }
469 
476 void vpPlot::getPixelValue(const bool block)
477 {
478  vpImagePoint iP;
479 
480  if (block)
481  vpDisplay::getClick(I, iP);
482  else
484 
485  for (unsigned int i = 0; i < graphNbr; i++) {
486  if ((graphList + i)->getPixelValue(I, iP))
487  break;
488  }
489 }
490 
498 void vpPlot::setTitle(const unsigned int graphNum, const std::string &title)
499 {
500  (graphList + graphNum)->setTitle(title);
501 }
502 
510 void vpPlot::setUnitX(const unsigned int graphNum, const std::string &unitx)
511 {
512  (graphList + graphNum)->setUnitX(unitx);
513 }
514 
522 void vpPlot::setUnitY(const unsigned int graphNum, const std::string &unity)
523 {
524  (graphList + graphNum)->setUnitY(unity);
525 }
526 
534 void vpPlot::setUnitZ(const unsigned int graphNum, const std::string &unitz)
535 {
536  (graphList + graphNum)->setUnitZ(unitz);
537 }
538 
547 void vpPlot::setLegend(const unsigned int graphNum, const unsigned int curveNum, const std::string &legend)
548 {
549  (graphList + graphNum)->setLegend(curveNum, legend);
550 }
551 
560 void vpPlot::resetPointList(const unsigned int graphNum)
561 {
562  for (unsigned int i = 0; i < (graphList + graphNum)->curveNbr; i++)
563  (graphList + graphNum)->resetPointList(i);
564 }
565 
574 void vpPlot::setThickness(const unsigned int graphNum, const unsigned int curveNum, const unsigned int thickness)
575 {
576  (graphList + graphNum)->setCurveThickness(curveNum, thickness);
577 }
578 
587 void vpPlot::setGraphThickness(const unsigned int graphNum, const unsigned int thickness)
588 {
589  for (unsigned int curveNum = 0; curveNum < (graphList + graphNum)->curveNbr; curveNum++)
590  (graphList + graphNum)->setCurveThickness(curveNum, thickness);
591 }
592 
601 void vpPlot::setGridThickness(const unsigned int graphNum, const unsigned int thickness)
602 {
603  (graphList + graphNum)->setGridThickness(thickness);
604 }
605 
615 void vpPlot::resetPointList(const unsigned int graphNum, const unsigned int curveNum)
616 {
617  (graphList + graphNum)->resetPointList(curveNum);
618 }
619 
646 void vpPlot::saveData(const unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix)
647 {
648  std::ofstream fichier;
649  fichier.open(dataFile.c_str());
650 
651  unsigned int ind;
652  double *p = new double[3];
653  bool end = false;
654 
655  std::vector<std::list<double>::const_iterator> vec_iter_pointListx((graphList + graphNum)->curveNbr);
656  std::vector<std::list<double>::const_iterator> vec_iter_pointListy((graphList + graphNum)->curveNbr);
657  std::vector<std::list<double>::const_iterator> vec_iter_pointListz((graphList + graphNum)->curveNbr);
658 
659  fichier << title_prefix << (graphList + graphNum)->title << std::endl;
660 
661  for (ind = 0; ind < (graphList + graphNum)->curveNbr; ind++) {
662  vec_iter_pointListx[ind] = (graphList + graphNum)->curveList[ind].pointListx.begin();
663  vec_iter_pointListy[ind] = (graphList + graphNum)->curveList[ind].pointListy.begin();
664  vec_iter_pointListz[ind] = (graphList + graphNum)->curveList[ind].pointListz.begin();
665  // (graphList+graphNum)->curveList[ind].pointListx.front();
666  // (graphList+graphNum)->curveList[ind].pointListy.front();
667  // (graphList+graphNum)->curveList[ind].pointListz.front();
668  }
669 
670  while (end == false) {
671  end = true;
672  for (ind = 0; ind < (graphList + graphNum)->curveNbr; ind++) {
673  // if (!(graphList+graphNum)->curveList[ind].pointListx.outside()
674  // &&
675  // !(graphList+graphNum)->curveList[ind].pointListy.outside()
676  // &&
677  // !(graphList+graphNum)->curveList[ind].pointListz.outside())
678  if ((vec_iter_pointListx[ind] != (graphList + graphNum)->curveList[ind].pointListx.end()) &&
679  (vec_iter_pointListy[ind] != (graphList + graphNum)->curveList[ind].pointListy.end()) &&
680  (vec_iter_pointListz[ind] != (graphList + graphNum)->curveList[ind].pointListz.end())) {
681  p[0] = *vec_iter_pointListx[ind];
682  p[1] = *vec_iter_pointListy[ind];
683  p[2] = *vec_iter_pointListz[ind];
684  // p[0] =
685  // (graphList+graphNum)->curveList[ind].pointListx.value();
686  // p[1] =
687  // (graphList+graphNum)->curveList[ind].pointListy.value();
688  // p[2] =
689  // (graphList+graphNum)->curveList[ind].pointListz.value();
690 
691  fichier << p[0] << "\t" << p[1] << "\t" << p[2] << "\t";
692  ++vec_iter_pointListx[ind];
693  ++vec_iter_pointListy[ind];
694  ++vec_iter_pointListz[ind];
695  // (graphList+graphNum)->curveList[ind].pointListx.next();
696  // (graphList+graphNum)->curveList[ind].pointListy.next();
697  // (graphList+graphNum)->curveList[ind].pointListz.next();
698  // if(!(graphList+graphNum)->curveList[ind].pointListx.nextOutside()
699  // &&
700  // !(graphList+graphNum)->curveList[ind].pointListy.nextOutside()
701  // &&
702  // !(graphList+graphNum)->curveList[ind].pointListz.nextOutside())
703  if ((vec_iter_pointListx[ind] != (graphList + graphNum)->curveList[ind].pointListx.end()) &&
704  (vec_iter_pointListy[ind] != (graphList + graphNum)->curveList[ind].pointListy.end()) &&
705  (vec_iter_pointListz[ind] != (graphList + graphNum)->curveList[ind].pointListz.end()))
706  end = false;
707  } else {
708  // p[0] =
709  // (graphList+graphNum)->curveList[ind].pointListx.value();
710  // p[1] =
711  // (graphList+graphNum)->curveList[ind].pointListy.value();
712  // p[2] =
713  // (graphList+graphNum)->curveList[ind].pointListz.value();
714  p[0] = (graphList + graphNum)->curveList[ind].pointListx.back();
715  p[1] = (graphList + graphNum)->curveList[ind].pointListy.back();
716  p[2] = (graphList + graphNum)->curveList[ind].pointListz.back();
717  fichier << p[0] << "\t" << p[1] << "\t" << p[2] << "\t";
718  }
719  }
720  fichier << std::endl;
721  }
722 
723  delete[] p;
724  fichier.close();
725 }
726 
727 #elif !defined(VISP_BUILD_SHARED_LIBS)
728 // Work arround to avoid warning: libvisp_core.a(vpPlot.cpp.o) has no symbols
729 void dummy_vpPlot(){};
730 #endif
Implementation of a generic rotation vector.
void initRange(const unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
Definition: vpPlot.cpp:228
bool inRectangle(const vpRect &rect) const
void setColor(const unsigned int graphNum, const unsigned int curveNum, vpColor color)
Definition: vpPlot.cpp:261
static bool getPointerPosition(const vpImage< unsigned char > &I, vpImagePoint &ip)
static bool getClick(const vpImage< unsigned char > &I, bool blocking=true)
vpImage< unsigned char > I
Definition: vpPlot.h:118
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:657
Implementation of row vector and the associated operations.
Definition: vpRowVector.h:115
Class to define colors available for display functionnalities.
Definition: vpColor.h:120
vpDisplayGDI()
Basic constructor.
Use the X11 console to display images on unix-like OS. Thus to enable this class X11 should be instal...
Definition: vpDisplayX.h:151
void setUnitX(const unsigned int graphNum, const std::string &unitx)
Definition: vpPlot.cpp:510
error that can be emited by ViSP classes.
Definition: vpException.h:71
void saveData(const unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix="")
Definition: vpPlot.cpp:646
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:291
void plot(const unsigned int graphNum, const unsigned int curveNum, const double x, const double y)
Definition: vpPlot.cpp:286
void setUnitY(const unsigned int graphNum, const std::string &unity)
Definition: vpPlot.cpp:522
void setTitle(const unsigned int graphNum, const std::string &title)
Definition: vpPlot.cpp:498
vpPlot()
Definition: vpPlot.cpp:61
Display for windows using Direct3D 3rd party. Thus to enable this class Direct3D should be installed...
Definition: vpDisplayD3D.h:107
void setGridThickness(const unsigned int graphNum, const unsigned int thickness)
Definition: vpPlot.cpp:601
void navigate(void)
Definition: vpPlot.cpp:439
#define vpTRACE
Definition: vpDebug.h:416
static void display(const vpImage< unsigned char > &I)
The vpDisplayOpenCV allows to display image using the OpenCV library. Thus to enable this class OpenC...
VISP_EXPORT void sleepMs(double t)
Definition: vpTime.cpp:258
The vpDisplayGTK allows to display image using the GTK 3rd party library. Thus to enable this class G...
Definition: vpDisplayGTK.h:138
void init(const unsigned int nbGraph, const unsigned int height=700, const unsigned int width=700, const int x=-1, const int y=-1, const std::string &title="")
Definition: vpPlot.cpp:100
virtual ~vpPlot()
Definition: vpPlot.cpp:130
unsigned int getRows() const
Definition: vpArray2D.h:289
void getPixelValue(const bool block)
Definition: vpPlot.cpp:476
void setLegend(const unsigned int graphNum, const unsigned int curveNum, const std::string &legend)
Definition: vpPlot.cpp:547
void initGraph(unsigned int graphNum, unsigned int curveNbr)
Definition: vpPlot.cpp:206
Implementation of column vector and the associated operations.
Definition: vpColVector.h:130
Implementation of a pose vector and operations on poses.
Definition: vpPoseVector.h:151
void resetPointList(const unsigned int graphNum)
Definition: vpPlot.cpp:560
void setGraphThickness(const unsigned int graphNum, const unsigned int thickness)
Definition: vpPlot.cpp:587
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
void setThickness(const unsigned int graphNum, const unsigned int curveNum, const unsigned int thickness)
Definition: vpPlot.cpp:574
Class that consider the case of a translation vector.
void setUnitZ(const unsigned int graphNum, const std::string &unitz)
Definition: vpPlot.cpp:534