Visual Servoing Platform version 3.5.0
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
61vpPlot::vpPlot() : I(), display(NULL), graphNbr(1), graphList(NULL), margei(30), margej(40), factori(1.f), factorj(1.)
62{
63}
81vpPlot::vpPlot(unsigned int graph_nbr, unsigned int height, unsigned int width, int x,
82 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
100void vpPlot::init(unsigned int graph_nbr, unsigned int height, unsigned int width, int x,
101 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
151void 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
206void 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// bool gx, bool gy)
213// {
214// (graphList+graphNum)->initScale(I,xmin,xmax,10,ymin,ymax,10,gx,gy);
215// }
216
228void vpPlot::initRange(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
247void vpPlot::initRange(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
261void vpPlot::setColor(unsigned int graphNum, unsigned int curveNum, vpColor color)
262{
263 (graphList + graphNum)->setCurveColor(curveNum, color);
264}
265
269void vpPlot::displayGrid()
270{
271 for (unsigned int i = 0; i < graphNbr; i++)
272 graphList[i].displayGrid(I);
273}
274
286void vpPlot::plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
287{
288 (graphList + graphNum)->plot(I, curveNum, x, y);
289}
290
302void vpPlot::plot(unsigned int graphNum, 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}
321void vpPlot::plot(unsigned int graphNum, 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
341void vpPlot::plot(unsigned int graphNum, 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}
360void vpPlot::plot(unsigned int graphNum, 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
380void vpPlot::plot(unsigned int graphNum, 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
402vpMouseButton::vpMouseButtonType vpPlot::plot(unsigned int graphNum, unsigned int curveNum, double x,
403 double y, double z)
404{
405 return (graphList + graphNum)->plot(I, curveNum, x, y, z);
406}
407
420vpMouseButton::vpMouseButtonType vpPlot::plot(unsigned int graphNum, 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
476void vpPlot::getPixelValue(bool block)
477{
478 vpImagePoint iP;
479
480 if (block)
482 else
484
485 for (unsigned int i = 0; i < graphNbr; i++) {
486 if ((graphList + i)->getPixelValue(I, iP))
487 break;
488 }
489}
490
498void vpPlot::setTitle(unsigned int graphNum, const std::string &title)
499{
500 (graphList + graphNum)->setTitle(title);
501}
502
510void vpPlot::setUnitX(unsigned int graphNum, const std::string &unitx)
511{
512 (graphList + graphNum)->setUnitX(unitx);
513}
514
522void vpPlot::setUnitY(unsigned int graphNum, const std::string &unity)
523{
524 (graphList + graphNum)->setUnitY(unity);
525}
526
534void vpPlot::setUnitZ(unsigned int graphNum, const std::string &unitz)
535{
536 (graphList + graphNum)->setUnitZ(unitz);
537}
538
547void vpPlot::setLegend(unsigned int graphNum, unsigned int curveNum, const std::string &legend)
548{
549 (graphList + graphNum)->setLegend(curveNum, legend);
550}
551
560void vpPlot::resetPointList(unsigned int graphNum)
561{
562 for (unsigned int i = 0; i < (graphList + graphNum)->curveNbr; i++)
563 (graphList + graphNum)->resetPointList(i);
564}
565
574void vpPlot::setThickness(unsigned int graphNum, unsigned int curveNum, unsigned int thickness)
575{
576 (graphList + graphNum)->setCurveThickness(curveNum, thickness);
577}
578
587void vpPlot::setGraphThickness(unsigned int graphNum, unsigned int thickness)
588{
589 for (unsigned int curveNum = 0; curveNum < (graphList + graphNum)->curveNbr; curveNum++)
590 (graphList + graphNum)->setCurveThickness(curveNum, thickness);
591}
592
601void vpPlot::setGridThickness(unsigned int graphNum, unsigned int thickness)
602{
603 (graphList + graphNum)->setGridThickness(thickness);
604}
605
615void vpPlot::resetPointList(unsigned int graphNum, unsigned int curveNum)
616{
617 (graphList + graphNum)->resetPointList(curveNum);
618}
619
646void vpPlot::saveData(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
729void dummy_vpPlot(){};
730#endif
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:291
unsigned int getRows() const
Definition: vpArray2D.h:289
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:88
bool inRectangle(const vpRect &rect) const
void init(unsigned int height, unsigned int width)
Set the size of the image.
Definition: vpImage.h:643
void initGraph(unsigned int graphNum, unsigned int curveNbr)
Definition: vpPlot.cpp:206
vpImage< unsigned char > I
Definition: vpPlot.h:118
void setUnitY(unsigned int graphNum, const std::string &unity)
Definition: vpPlot.cpp:522
virtual ~vpPlot()
Definition: vpPlot.cpp:130
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:100
void initRange(unsigned int graphNum, double xmin, double xmax, double ymin, double ymax)
Definition: vpPlot.cpp:228
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:547
void plot(unsigned int graphNum, unsigned int curveNum, double x, double y)
Definition: vpPlot.cpp:286
void setUnitX(unsigned int graphNum, const std::string &unitx)
Definition: vpPlot.cpp:510
void setColor(unsigned int graphNum, unsigned int curveNum, vpColor color)
Definition: vpPlot.cpp:261
void setThickness(unsigned int graphNum, unsigned int curveNum, unsigned int thickness)
Definition: vpPlot.cpp:574
void navigate(void)
Definition: vpPlot.cpp:439
void setGraphThickness(unsigned int graphNum, unsigned int thickness)
Definition: vpPlot.cpp:587
vpPlot()
Definition: vpPlot.cpp:61
void setUnitZ(unsigned int graphNum, const std::string &unitz)
Definition: vpPlot.cpp:534
void setTitle(unsigned int graphNum, const std::string &title)
Definition: vpPlot.cpp:498
void saveData(unsigned int graphNum, const std::string &dataFile, const std::string &title_prefix="")
Definition: vpPlot.cpp:646
void resetPointList(unsigned int graphNum)
Definition: vpPlot.cpp:560
void getPixelValue(bool block)
Definition: vpPlot.cpp:476
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)