I’m trying to use a particles previous position to draw a line to its current position but they are always equal even though previous position is got before the position is updated?
So I’m following Coding Challenge #24: Perlin Noise Flow Field but doing it in processing instead and I can’t seem to understand why I can’t replicate the last step of the video.
Full code at the bottom of the post.
This is the function I’m executing:
void updatePrevPos() {
prevPos.x = pos.x;
prevPos.y = pos.y;
}
This is the block of code that shows what functions are being executed on the individual particles in the canvas:
for (Particle particle : particles) {
//Checks if particle has hit any edge and corrects the position accordingly
particle.edges();
//Adds a force to the particle depending where it is in the flow field
particle.follow(flowField);
//Updates the particles position, velocity and acceleration vectors
particle.update();
//Draws the particle
particle.show();
}
So I want to get the position the particle is in right before its updated. Logically, I thought, I should call updatePrevPos() right before the line that updates the position of the particle then. Here is the code that executes when particle.update() is run:
public void update() {
updatePrevPos();
vel.limit(maxSpeed);
vel.add(acc);
pos.add(vel);
print(pos == prevPos);
acc.mult(0);
}
I tried calling the function everywhere before pos.add() is executed but I always get “true” printed even though updatePrevPos() is not called anywhere else. pos does change but somehow prevPos changes with it in the same frame?
Please, help.
Thanks.
Full code:
float inc = 0.1;
int scale = 10;
int cols, rows;
int nParticles = 1;
//Tids variabel. Förändring i zoff är en förändring i tid.
float zoff = 0;
ArrayList<Particle> particles = new ArrayList<Particle>();
PVector[][] flowField;
void setup() {
size(1300, 900);
background(255);
cols = floor(width / scale);
rows = floor(height / scale);
for (int i = 0; i < nParticles; i++) {
particles.add(new Particle());
}
flowField = new PVector[cols][rows];
print("rows: " + rows + " ");
print("cols: " + cols + " ");
}
void draw() {
//background(255);
float yoff = 0;
for (int y = 0; y < rows; y++) {
float xoff = 0;
for (int x = 0; x < cols; x++) {
//Hittar en slumpmässig vinkel för vektorerna baserad på perlin noise.
float angle = noise(xoff, yoff, zoff) * TWO_PI * 3;
//Skapar en enhetsvektor med den uträknade vinkeln angle och lägger den i flowField
PVector v = PVector.fromAngle(angle);
v.setMag(1);
flowField[x][y] = v;
xoff += inc;
stroke(0);
//Byter referenspunkt till varje hörn i våran "matris" och ritar en
//linje som är roterad med samma vinkel som vektorn
pushMatrix();
//translate(x*scale,y*scale);
//rotate(v.heading());
//stroke(0,50);
//strokeWeight(1);
//line(0, 0, scale, 0);
popMatrix();
}
yoff += inc;
}
zoff += 0.005;
//Rendera och uppdatera varje partikel
for (Particle particle : particles) {
particle.edges();
particle.follow(flowField);
particle.update();
particle.show();
}
//print("Frame rate = " + floor(frameRate) + " ");
}
//Partikel objekt
class Particle {
PVector pos = new PVector(random(width), random(height));
PVector vel = new PVector(0, 0);
PVector acc = new PVector(0, 0);
int maxSpeed = 5;
PVector prevPos = pos;
//Fysik-motor
public void update() {
updatePrevPos();
vel.limit(maxSpeed);
vel.add(acc);
pos.add(vel);
print(pos == prevPos);
acc.mult(0);
}
void updatePrevPos() {
prevPos.x = pos.x;
prevPos.y = pos.y;
}
public void applyForce(PVector force) {
acc.add(force);
}
public void show() {
//Justera alpha för att få olika utveckling på bild
stroke(floor((vel.heading() * 255)/TWO_PI), 0, floor((pos.heading() * 255)/TWO_PI), 255);
strokeWeight(2);
line(pos.x, pos.y, prevPos.x, prevPos.y);
}
public void edges() {
if (pos.x > width) {
pos.x = 0;
updatePrevPos();
}
if (pos.x < 0) {
pos.x = width;
updatePrevPos();
}
if (pos.y > height) {
pos.y = 0;
updatePrevPos();
}
if (pos.y < 0) {
pos.x = height;
updatePrevPos();
}
}
public void follow(PVector[][] flowField) {
int x = floor(pos.x / scale) - 1;
int y = floor(pos.y / scale) - 1;
if (x < 0) x = 0;
if (y < 0) y = 0;
PVector force = flowField[x][y];
applyForce(force);
}
}