Plot grafica in Pgraphics?

Seems like the library grafica doesn’t offer us any option to change the PGraphics it draws onto. It directly calls PApplet’s methods to draw on its canvas. :disappointed:

The workaround I’ve come up w/ is to wrap up the grafica’s code on its own PApplet subclass. :gift:

And then call PSurface::setVisible() in order to hide its window. :dark_sunglasses:

And in order to save its current canvas, I’ve added a pre() method to it:

void pre() {
  unregisterMethod("pre", this);
  saveFrame(dataPath(FILENAME));
}

Which then I use PApplet::registerMethod() inside main PApplet’s mousePressed() callback so the grafica’s PApplet runs its pre() callback once:

void mousePressed() {
  if (mouseButton == CENTER)  graf.registerMethod("pre", graf);
  else  graf.getSurface().setVisible(visible ^= true);
  redraw = true;
}

I’m using grafica’s “MovingPoints.pde” example sketch as a base for my workaround:

Here’s my full workaround sketch: :cowboy_hat_face:

/**
 * PApplet Grafica (v1.0.1)
 * GoToLoop (2018/Aug/03)
 * Discourse.Processing.org/t/plot-grafica-in-pgraphics/2334/2
 */

import grafica.*;

PApplet graf;
boolean visible;

void settings() {
  size(600, 400);
  noLoop();

  final String[] switches = { "--sketch-path=" + sketchPath(), "" };
  runSketch(switches, graf = new Grafica());

  while (graf.height <= 100)  delay(1);
  graf.getSurface().setVisible(visible);
}

void draw() {
  background((color) random(#000000));
}

void mousePressed() {
  if (mouseButton == CENTER)  graf.registerMethod("pre", graf);
  else  graf.getSurface().setVisible(visible ^= true);
  redraw = true;
}

public static class Grafica extends PApplet {
  static final String NAME = "plot-####", EXT = ".jpg";
  static final String FILENAME = NAME + EXT;

  GPlot plot;
  int step = 0;
  int stepsPerCycle = 100;
  int lastStepTime = 0;
  boolean clockwise = true;
  float scale = 5;

  void pre() {
    unregisterMethod("pre", this);
    saveFrame(dataPath(FILENAME));
  }

  void settings() {
    size(450, 450);
  }

  void setup() {
    // Prepare the first set of points
    int nPoints1 = stepsPerCycle/10;
    GPointsArray points1 = new GPointsArray(nPoints1);

    for (int i = 0; i < nPoints1; i++) {
      points1.add(calculatePoint(step, stepsPerCycle, scale));
      step = (clockwise)? step + 1 : step - 1;
    }

    lastStepTime = millis();

    // Prepare the second set of points
    int nPoints2 = stepsPerCycle + 1;
    GPointsArray points2 = new GPointsArray(nPoints2);

    for (int i = 0; i < nPoints2; i++) {
      points2.add(calculatePoint(i, stepsPerCycle, 0.9*scale));
    }

    // Create the plot
    plot = new GPlot(this);
    plot.setPos(25, 25);
    plot.setDim(300, 300);
    // or all in one go
    // plot = new GPlot(this, 25, 25, 300, 300);

    // Set the plot limits (this will fix them)
    plot.setXLim(-1.2*scale, 1.2*scale);
    plot.setYLim(-1.2*scale, 1.2*scale);

    // Set the plot title and the axis labels
    plot.setTitleText("Clockwise movement");
    plot.getXAxis().setAxisLabelText("x axis");
    plot.getYAxis().setAxisLabelText("y axis");

    // Activate the panning effect
    plot.activatePanning();

    // Add the two set of points to the plot
    plot.setPoints(points1);
    plot.addLayer("surface", points2);

    // Change the second layer line color
    plot.getLayer("surface").setLineColor(color(100, 255, 100));
  }

  void draw() {
    background(150);

    plot.beginDraw();
    plot.drawBackground();
    plot.drawBox();
    plot.drawXAxis();
    plot.drawYAxis();
    plot.drawTopAxis();
    plot.drawRightAxis();
    plot.drawTitle();
    plot.getMainLayer().drawPoints();
    plot.getLayer("surface").drawFilledContour(GPlot.HORIZONTAL, 0);
    plot.endDraw();

    // Add and remove new points every 10th of a second
    if (millis() - lastStepTime > 100) {
      if (clockwise) {
        // Add the point at the end of the array
        plot.addPoint(calculatePoint(step, stepsPerCycle, scale));
        step++;

        // Remove the first point
        plot.removePoint(0);
      } else {
        // Add the point at the beginning of the array
        plot.addPoint(0, calculatePoint(step, stepsPerCycle, scale));
        step--;

        // Remove the last point
        plot.removePoint(plot.getPointsRef().getNPoints() - 1);
      }

      lastStepTime = millis();
    }
  }

  void mouseClicked() {
    // Change the movement sense
    clockwise = !clockwise;

    if (clockwise) {
      step += plot.getPointsRef().getNPoints() + 1;
      plot.setTitleText("Clockwise movement");
    } else {
      step -= plot.getPointsRef().getNPoints() + 1;
      plot.setTitleText("Anti-clockwise movement");
    }
  }

  GPoint calculatePoint(float i, float n, float rad) {
    float delta = 0.1*cos(TWO_PI*10*i/n);
    float ang = TWO_PI*i/n;
    return new GPoint(rad*(1 + delta)*sin(ang), rad*(1 + delta)*cos(ang));
  }
}
2 Likes