Search code examples
navigationdrawingprocessingreal-time

Navigation bar in Processing for bigger than screen drawing


I'm having trouble moving the perspective in a 10000 pixel wide window, in which I am performing a drawing every millisecond or so, and all the drawings are stacking in the x direction. I want to be able to move the perspective that is shown on my screen along the x axis where I want it to, so that i can see the real time drawing happening.

I am using the light sensor on an Arduino-type board to communicate to the PDE the light levels, and I am drawing a Bezier curve for each instance of the light read, making the Bezier wider when the light is dim, and narrower when the light is intense.

The Beziers covering all the screen allready

I am trying to implement a navigator bar of this type:

    void setup()
{
  size(1800, 1800);
}

void draw()
{ int x_navigator = width / 2 - width / 6, y_navigator = 80, navigator_width = width / 3, navigator_height = 40;
  fill(204);
  rect(x_navigator, y_navigator, navigator_width, navigator_height);
  fill(250, 204, 0, 160);
  if (mouseX > x_navigator && mouseY > y_navigator && mouseX < x_navigator + navigator_width && mouseY < y_navigator + navigator_height)
  {
    if (mouseX < x_navigator + navigator_width / 12)
    {
      rect(x_navigator, y_navigator, navigator_width / 6, navigator_height);
    }
    else
    {
      if (mouseX > x_navigator + ((11 * navigator_width) / 12))
      {
        rect(x_navigator + (5 * navigator_width) / 6, y_navigator, navigator_width / 6, navigator_height);
      }
      else
      {
        rect(mouseX - (navigator_width / 12), y_navigator, navigator_width / 6, navigator_height);
      }
    }
  }
}

on my code that draws Beziers:

import processing.serial.*;

Serial Engduino;
String light_String = "", temperature_String = "";
int constant = 300;
float begin_x = 0, begin_y = 550, end_x, end_y, control = 1, light, temperature;

    void setup()
    {
      String portName = "COM3";
      Engduino = new Serial(this, portName, 9600);
      size(1000, 800);
      noFill();
      smooth();
      strokeWeight(3);
    }

    void draw()
    {
      if (Engduino.available() > 0) 
      {
        light_String = Engduino.readStringUntil('\n');
        try{light = parseFloat(light_String);}
        catch(NullPointerException e)
        {;}
        println("The light is: ");
        println(light);
        end_x = begin_x + (400 / (sqrt(light) + 1));
        end_y = begin_y - constant;
        control = end_x - begin_x;
        bezier(begin_x, begin_y, begin_x + control, begin_y, end_x - control, end_y, end_x, end_y);
        constant = constant * (-1);
        begin_x = end_x;
        begin_y = end_y;
      }
    }

While making it functional as to move the displayed image where the cursor is, so that I can see the drawing in real time, and also to check the previous curves drawn if I so wish.

EDIT: So the code that works without an Engduino is this:

int constant = 300;
float begin_x = 0, begin_y = 550, end_x, end_y, control = 1, light = 30; // Light is what I get through the serial port from the Engduino (an Arduino type board`)

void setup()
{
  size(10000, 800); // The 10000-pixel wide window.
  noFill();
  smooth();
  strokeWeight(3);
}

void draw()
{
    end_x = begin_x + (400 / (sqrt(light) + 1));
    end_y = begin_y - constant;
    control = end_x - begin_x;
    bezier(begin_x, begin_y, begin_x + control, begin_y, end_x - control, end_y, end_x, end_y);
    constant = constant * (-1);
    begin_x = end_x;
    begin_y = end_y;
}

What I want is to have a navigation bar of the type I've shown (at least in design) to navigate around the 10000-pixel wide window. The navigation bar code I have uploaded is only a design of the navigation, and has no functionality, that's where I want some help.


Solution

  • This is going to be a little complicated just because your drawing is done over multiple frames. You're not clearing the canvas every frame, you're building up a drawing over time.

    If you were clearing the canvas and redrawing everything each frame (which is what many Processing sketches do), then you could simply change the X value of where you're drawing everything, or simply call the translate() function before drawing everything else.

    But since you're drawing everything over multiple frames, you're going to have to draw to a PGraphics buffer. Then on each frame, you draw the buffer using whatever X offset you want. Here's a little example:

    int constant = 300;
    float begin_x = 0, begin_y = 550, end_x, end_y, control = 1, light = 30; // Light is what I get through the serial port from the Engduino (an Arduino type board`)
    
    PGraphics pg;
    
    void setup()
    {
      size(10000, 800); // The 10000-pixel wide window.
      pg = createGraphics(width, height);
    }
    
    void draw()
    {
    
      end_x = begin_x + (400 / (sqrt(light) + 1));
      end_y = begin_y - constant;
      control = end_x - begin_x;
    
      pg.beginDraw();
      pg.noFill();
      pg.smooth();
      pg.strokeWeight(3);
      pg.bezier(begin_x, begin_y, begin_x + control, begin_y, end_x - control, end_y, end_x, end_y);
      pg.endDraw();
    
      constant = constant * (-1);
      begin_x = end_x;
      begin_y = end_y;
    
      background(200);
      image(pg, -mouseX, 0);
    }