Printing all PVector coordinates stored in an ArrayList

I’m trying to get the whole set of x, y coordinates that are stored in an array.

ArrayList<Points> recorded = new ArrayList(); 



void store (float x, float y) {
  
  int ArrayListSize = recorded.size()-1;
 
  if (ArrayListSize>=0) {
    PVector p1 = recorded.get(ArrayListSize).p1; 
 
    if (p1.x!=x || p1.y!=y)
      recorded.add(new Points(x, y));
     println(x);
     println(y + ",");
  } 
  else {
    recorded.add(new Points(x, y));
  }
}




class Points {
 
  PVector p1;
 
  Points(float x_, float y_) {
 
    p1=new PVector(x_, y_);
  }
  
}

These lines:

 println(x);
 println(y + ",");

just print while drawing. And a code like this:

      if (recorded.size() == 100) {
      for (int i = 0; i < 100; i++)  {
        println(recorded.get(i));
      }
      }

Just returns the index numbers like sketch$Points@39a69ce2

What is the way to get the list of x,y values all at once after reaching a certain number of them? (in my example it’s the 100th)

Like this:

141.60295
528.31396,
148.41893
538.1505,

etc

Hi @papaboo,

My suggestion would be to simplify things :slight_smile:
So the PVector stores already x and y, so you don’t need a new class

Find my example below. Everytime you click on the canvas, the mouse coordinates are added to the record. Once you have clicked 10 times (in this case), all previous records will be printed :slight_smile:

ArrayList<PVector> recorded = new ArrayList(); 


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

void draw() {  
}

void mousePressed() {
  recorded.add(new PVector(mouseX, mouseY)); //Add new coordinates to ArrayList
  int idxLastRecord = recorded.size()-1; //Get the last added position in the array
  println("Add to record: " + recorded.get(idxLastRecord).x + ", " + recorded.get(idxLastRecord).y); //Print the coordinates

  if (recorded.size() == 10) { //If the size is ten, print all
    println("I am the one! PRINTING THEM ALL! ");
    for (int i = 0; i < recorded.size(); i++) {
      println("X = " + recorded.get(i).x + ", Y = " + recorded.get(i).y);
    }
    println("--------------------------");
  }
}

Hope it helps!
Best regards

1 Like

Thanks @MiguelSanches but I still don’t understand why a statement like this doesn’t work for my code :

  if (recorded.size() == 100) {
      for (int i = 0; i < 100; i++)  {
        println("X = " + recorded.get(i).x + ", Y = " + recorded.get(i).y);
      }
      }

Why does it give an error when I add .x or .y after get(i) ?
That was my question, basically.

Are you running those line in your code you posted above? With ArrayList<Points> recorded ?

Then here

recorded.get(i).x 

you forgot p1 (which is located in the class Points), no?

recorded.get(i).p1.x 

because ArrayList is of type Points

Chrisir

2 Likes

another version



ArrayList<PVector> recorded = new ArrayList(); 

void setup() {
  size(1110, 400);
  background(0);
}

void draw() {
  background(0); 
  for (PVector pv : recorded)   // short form of for-loop
    ellipse(pv.x, pv.y, 7, 7);
}

void mousePressed() {
  //Add new coordinates to ArrayList
  recorded.add(new PVector(mouseX, mouseY)); 

  //Get the last added position in the array
  PVector pvTest = recorded.get(recorded.size()-1);
  println("Add to record: "  
    +pvToString(pvTest)); //Print the coordinates

  if (recorded.size() == 10) { //If the size is ten, print all
    println("I am the one! PRINTING THEM ALL! ");
    for (PVector pv : recorded)
      println(pvToString(pv));

    println("--------------------------");
  }
}

// function to get String from PVector
String pvToString (PVector pv) {
  return
    "X = " + pv.x 
    + ", Y = " + pv.y;
}

Other examples w/ toString(): :nerd_face:




1 Like

Thanks @Chrisir, I’ve got another question related to this. To animate an object (a red circle in this particular example) along the points drawn; I’m using the code below in draw() but the red circle ends up at the end of the path (at the last vertex in the array).

I thought for loop in Processing was iterating each time a new frame is created in draw() function, relative to the frame rate. But this one happens all at once. I searched the forum and the answers suggested using lerp(), which wouldn’t work in my case because the time between two point is set to 1 frame- irrespective of the distance between them. Should I use millis or pushMatrix, popMatrix? Keep in mind this is a 120fps power-intensive sketch, so I’m really confused.

Here’s the loop:

if (readyToAnimate && mouseX > 1000) {
    for (int i = 0; i < recorded.size() - 1; i++) {
      background(48);
      fill(255, 0,0);
      ellipse((recorded.get(i).p1.x), recorded.get(i).p1.y, 30, 30);
    
    }
}

Explanation

draw() updates the screen only one time at its end.

Therefore you cannot see any animation done with a for loop.

Get rid of the for loop and then use the fact that draw is looping in itself.

So make i a global variable and increase it with i++;

When i is >= size() of the list say i = 0; to restart

The lerp() command

Later you can use lerp() too. It would help to calculate and show the minor points between each or two points in the chain. So the animation gets more smooth. You would need i2 to do this and reset i2 every time you reach a point (which you received by i).

Normally we use a fixed number of steps (amt parameter in the reference for lerp()) between two points. To have always the same speed of the animation, we could calculate the number of steps based on the distance of the two current points.

Chrisir