Trouble with Vector.add

Hi,

I am in trouble with the p5.Vector.add() method and I don’t see why.
My code generates a 2D Vector in setup, adds a random 2D vector in draw, pushes the result in an array and draws the whole array in a loop. If I add the vectors with
v.add(vr);
I get an array with identical vectors in it and nothing works, if I use the static method
v = p5.Vector.add(v,vr);
everything works fine and I don’t understand why.
Here’s the code:

let v;
let path = [];

function setup() {
  createCanvas(600, 600);
  v = createVector(200, 200);
}

function draw() {
  background(220);
  let vr = p5.Vector.random2D();
  
  v.add(vr); // this does not work
  //v = p5.Vector.add(v,vr); // this does
  path.push(v);
  
  for (i = 0; i < path.length - 1; i++) {
    line(path[i].x, path[i].y, path[i+1].x, path[i+1].y);
  }
}
1 Like

This is down to a little quirk of JavaScript…

When you write v.add(vr), you are adding vr to the p5 vector object v. This makes intuitive sense.

However, it gets a little confusing when you push v into the array path. Because of the way JavaScript deals with objects (by reference rather than by value), the v you have pushed to the array is not its own new vector as you might expect, but rather it refers to the same object as the v that you define at the top of your code. As a result, when you call v.add(vr), you are referring to not only to the v you originally defined, but any other v that you have used elsewhere.
This means when you add vr to v, you are adding the vector to all of the vectors in the path array, so they all move simultaneously, meaning that when lines are drawn between them, they just appear as a single point.

A simple solution to this (other than using p5.Vector.add) is to push v.copy() instead of v. This uses the p5 vector copy method which creates a new identical vector, which does not refer to the original vector object (v), meaning that if v is changed, this copy will not be.

The reason that v = p5.Vector.add(v,vr); does not produce the same problem is that the v object is replaced with a new vector object every time you push a vector to the array. This means that v no longer refers to the vectors pushed to the array, so changing it does not affect the vectors already in the array.

2 Likes

Hi TheWizardBear,

Thank you so much for that clear explanation. I understand that now, it’s good to know and I think it’s a nice feature to have both options.

1 Like

I didn’t ask the question yet I had a feeling I would learn something valuable. Wasn’t disappointed. Thanks!

1 Like