lagadic / visp

Open Source Visual Servoing Platform
https://visp.inria.fr/
GNU General Public License v2.0
709 stars 287 forks source link

Is there any way to display Greek letters in the legend? #916

Closed allbluelai closed 2 years ago

allbluelai commented 3 years ago

I want to use vpPlot::setLegend to set the title with Greek alphabet. I set in my code:

plotter->setLegend( 0, 0, "W\u0394\u03B8_p1_x" );

Picture1 Fail to display Greek letters

something like $2\pi$

fspindle commented 3 years ago

This feature is unfortunately not implemented

s-trinh commented 2 years ago

Actually it is possible, at least on Ubuntu/Unix system:

image

It is with -urw-standard symbols l-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific font. Did not found a better font to mix classical and Greek fonts, but probably there is.

I did different things so I don't know exactly the correct procedure. Anyway, it should be something like:

It gives something like this when playing randomly with it (need to read the doc to understand the meaning of each option):

image

This link seems to be useful to understand the options.


Let's convert this issue into a feature request.

s-trinh commented 2 years ago

Small update.

With https://github.com/lagadic/visp/pull/987 it is now possible to draw text using the font of your choice. But you have to position/handle the text yourself.

Example using https://github.com/googlefonts/Rubik:

image


Quick and dirty code is:

/*! \example tutorial-ibvs-4pts-plotter-continuous-gain-adaptive.cpp */
#include <visp3/core/vpFont.h>
#include <visp3/gui/vpPlot.h>
#include <visp3/gui/vpDisplayX.h>
#include <visp3/robot/vpSimulatorCamera.h>
#include <visp3/visual_features/vpFeatureBuilder.h>
#include <visp3/vs/vpServo.h>

int main()
{
  try {
    vpHomogeneousMatrix cdMo(0, 0, 0.75, 0, 0, 0);
    vpHomogeneousMatrix cMo(0.15, -0.1, 1., vpMath::rad(10), vpMath::rad(-10), vpMath::rad(50));

    vpPoint point[4];
    point[0].setWorldCoordinates(-0.1, -0.1, 0);
    point[1].setWorldCoordinates(0.1, -0.1, 0);
    point[2].setWorldCoordinates(0.1, 0.1, 0);
    point[3].setWorldCoordinates(-0.1, 0.1, 0);

    vpServo task;
    task.setServo(vpServo::EYEINHAND_CAMERA);
    task.setInteractionMatrixType(vpServo::CURRENT);

    vpAdaptiveGain lambda(4, 0.4, 30);
    task.setLambda(lambda);

    vpFeaturePoint p[4], pd[4];
    for (unsigned int i = 0; i < 4; i++) {
      point[i].track(cdMo);
      vpFeatureBuilder::create(pd[i], point[i]);
      point[i].track(cMo);
      vpFeatureBuilder::create(p[i], point[i]);
      task.addFeature(p[i], pd[i]);
    }

    vpHomogeneousMatrix wMc, wMo;
    vpSimulatorCamera robot;
    robot.setSamplingTime(0.040);
    robot.getPosition(wMc);
    wMo = wMc * cMo;

#ifdef VISP_HAVE_DISPLAY
    vpPlot plotter(2, 250 * 2, 500, 100, 200, "Real time curves plotter");
//    plotter.setTitle(0, "Visual features error");
    plotter.setTitle(1, "Camera velocities");

    plotter.initGraph(0, 8);
    plotter.initGraph(1, 6);

    plotter.setLegend(0, 0, "x1");
    plotter.setLegend(0, 1, "y1");
    plotter.setLegend(0, 2, "x2");
    plotter.setLegend(0, 3, "y2");
    plotter.setLegend(0, 4, "x3");
    plotter.setLegend(0, 5, "y3");
    plotter.setLegend(0, 6, "x4");
    plotter.setLegend(0, 7, "y4");

    plotter.setLegend(1, 0, "v_x");
    plotter.setLegend(1, 1, "v_y");
    plotter.setLegend(1, 2, "v_z");
    plotter.setLegend(1, 3, "w_x");
    plotter.setLegend(1, 4, "w_y");
    plotter.setLegend(1, 5, "w_z");

    //TODO:
    vpImage<vpRGBa> customPlotter(plotter.I.getHeight(), plotter.I.getWidth());
    vpDisplayX d;
    d.init(customPlotter, customPlotter.getWidth(), 200, "Graph plotting using manual vpDisplay");
    vpFont font;
#endif

    unsigned int iter = 0;
    while (1) {
      robot.getPosition(wMc);
      cMo = wMc.inverse() * wMo;
      for (unsigned int i = 0; i < 4; i++) {
        point[i].track(cMo);
        vpFeatureBuilder::create(p[i], point[i]);
      }
      vpColVector v = task.computeControlLaw(iter * robot.getSamplingTime());
      robot.setVelocity(vpRobot::CAMERA_FRAME, v);

#ifdef VISP_HAVE_DISPLAY
      plotter.plot(0, iter, task.getError());
      plotter.plot(1, iter, v);

      //TODO:
      vpDisplay::getImage(plotter.I, customPlotter);
      std::string customTitle = "Graphe temps réel : ∑ \u2211 \u221E";
      vpImagePoint titlePos = font.getMeasure(customTitle);
      font.drawText(customPlotter, customTitle, vpImagePoint(15, (500-titlePos.get_u())/2), vpColor::red);
      vpDisplay::display(customPlotter);
      vpDisplay::flush(customPlotter);
#endif
      if ((task.getError()).sumSquare() < 0.0001)
        break;

      vpTime::wait(100);

      iter++;
    }
    std::cout << "Convergence in " << iter << " iterations" << std::endl;

#ifdef VISP_HAVE_DISPLAY
    plotter.saveData(0, "error.dat");
    plotter.saveData(1, "vc.dat");

    //TODO:
    font.drawText(plotter.I, "TEST", vpImagePoint(15, 223), 255);

    vpDisplay::getClick(plotter.I);
#endif
  } catch (const vpException &e) {
    std::cout << "Catch an exception: " << e << std::endl;
  }
}