How do I draw a continuous line between several points?


#1

I’d like to draw a continuous line between several points. It should be any shape what so ever and not fill anything between any of the points, like drawing with a pen. Picture for reference:

ConnectingDots

I know that if I don’t update the background every drawn frame I can get a similar result by just drawing a line between a dot and its previous position but in this instance, I want to be able to draw other things in the background that I do want to update the background for.

I was thinking of using vertex() where I might save all the points and then use them as vertices but I don’t have any clue how to do this as I seem to have to write actual code for every vertex manually…

Help much appreciated!

Thanks.


#2

How about an array with all values?

Float [ ] [ ] values = new float [amount points][2]

First dimension is the “id” of your point, the secnd one is the x and the y value.
Then using a for-loop to draw all lines between all neighbor points.


#3

Maybe curveVertex will be more useful for what you want to do. Vextex will draw straight lines between two points, and not curves.
For drawing on a layer wich is above your background, use Pgraphics :

PGraphics pg; // declare the instance of the layer ( called buffer)

void setup() {
  size(900, 900);
  pg = createGraphics(width, height); //initialize it to the size of your window
}

void draw() {
 // to draw in your buffer, use the noun of your variable before ; here pg
  pg.beginDraw(); //always declare beginDraw and endDraw when you draw a shape into your buffer

// your shapes

  pg.endDraw(); 
  image(pg,0,0); // then display your buffer on screen ; otherwise, you won't see what you draw in
}

So you can use a buffer to draw your shape “drawn by hand” and like this, you can change the background without cover it.


#4

vertex for line good,
like @Pr0tonX suggested curveVertex more round,
https://processing.org/reference/curveVertex_.html
and you can combine it with
https://processing.org/reference/createShape_.html

but i think that is all not the question,
where / how you get the points for the curve?

if you want fill them manually
instead of hard coded or loaded from a .csv file
you could click with the mouse and remember that point
in a PVector
https://processing.org/reference/PVector.html
of a array of PVector
https://processing.org/reference/Array.html

like
PVector[] my_points;
int pmx, pmy, make = 0, makemax=20;

void setup() {
  size(200, 200);
  my_points = new PVector[makemax];
  println("can make by mouse click "+makemax+" points now");
}

void draw() {
  background(200, 200, 0);
  stroke(200, 0, 0);
  ellipse(pmx, pmy,2,2);
  // you do later
}

void mousePressed() {
  pmx = mouseX;
  pmy = mouseY;
  my_points[make] = new PVector(pmx, pmy);
  println("i: "+make+" px: "+my_points[make].x+" py: "+my_points[make].y);
  make++;
  if ( make >= makemax ) {
    make = 0;
    println(" array full, now you will overwrite ");
  }
}


#5

You might also want an ArrayList of PVectors to store mouse points for your curveVertex calls.

Here is a simple example of drawing curve points with a mouse. Note that the mouse points are so close together that it almost doesn’t matter that you are using a curve – you would get almost the same curvy effect from connecting them with straight lines.

// CurvePoints -- Processing 3.3.6 -- 2018-12-06

int maxPoints = 500;

ArrayList<PVector> points;
void setup() {
  size(400, 400);
  points = new ArrayList<PVector>();
  noFill();
}
void draw() {
  background(192);
  // draw curve
  beginShape();
  if (points.size()>0) {
    for (PVector p : points) {
      curveVertex(p.x, p.y);
    }
  }
  endShape();
}
void mouseMoved() {
  points.add(new PVector(mouseX, mouseY));
  // erase from back of line
  if (points.size() > maxPoints) {
    println(points.size());
    points.remove(0);
  }
}

Note also that there is a bit of extra code here that erases points from the back of the line. This is to prevent you from drawing so many points that the sketch bogs down and stops – which is even more important if you are adding points in draw() every frame rather than in mouseMoved(), as you will quickly have thousands of points at 60 points-per-second.

There are a lot of little things you could add to making curve drawling like this behave in a pleasing or intuitive way – deciding how new points are added (by distance, time, or both), figuring out how the anchors should work, making aspects of the curve adjustable, and so on. Here is a more complex implementation of the same approach along with a bit of code that flashes the points on and off.

Summary
ArrayList<PVector> points;
int maxPoints = 50;
int markDistance = 50;

void setup() {
  size(400, 400);
  points = new ArrayList<PVector>();
  noFill();
}
void draw() {
  background(192);
  // draw curve
  beginShape();
  if (points.size()>0) {
    // begin anchor
    curveVertex(points.get(0).x, points.get(0).y);
    // curve points
    for (PVector p : points) {
      curveVertex(p.x, p.y);
      // turn on and off point markers 
      if (millis()/2000%2==0) {
        ellipse(p.x, p.y, 3, 3);
      }
    }
    // end anchor
    curveVertex(points.get(points.size()-1).x, points.get(points.size()-1).y);
  }
  endShape();
}
void mouseMoved() {
  // add point when new is distant from old
  if (points.size()<2 || points.get(points.size()-2).dist(new PVector(mouseX, mouseY)) > markDistance) {
    points.add(new PVector(mouseX, mouseY));
    // erase from back of line
    if (points.size() > maxPoints) {
      println(points.size());
      points.remove(0);
    }
  } else {
    // nudge -- update last point if too close to previous
    points.set(points.size()-1, new PVector(mouseX, mouseY));
  }
}
void keyPressed(){
  // delete previous points
  if(points.size()>2 && key==DELETE || key==BACKSPACE){
    points.remove(points.size()-2);
  }
}

CurveDraw2--screenshot

You may also be interested in this tutorial series, particularly the parts beginning at “Limited Trail”

http://www.science.smith.edu/dftwiki/index.php/Creating_a_trail_of_moving_object_in_Processing#Limited_Trail


#6

Thank you very much for the answer! I landed on a more simple solution because I could afford to have a really high refresh rate on putting points down. This seems like a more elegant solution for fewer points though! Thanks!