Where does this code break? (The Coding Train Challenge #24)

edited March 2017 in Questions about Code

I was following a tutorial about generating a Perlin Noise flow field in p5.js (The Coding Train Challenge #24) and I had a rough time converting from p5.js to Processing. This code was supposed to generate a field of vectors using perlin noise, then place particles and move them along the vector angles.

At line 17 from the Particle class, I got an ArrayIndexOutOfBoundsException, (PVector force = vectors[index];) although I have no idea how I can fix that. The code works fine until that line.

Here's the code:

PVector v; 

int scl = 20;
int rows = 30;
int cols = 40;

float inc = 0.1;
float xoff;
float yoff;
float zoff = 0;

Particle[] particles = new Particle[100];
PVector[] flowfield = new PVector[cols * rows];

void setup() {
  size(800, 600);
  stroke(0);
  for (int i = 0; i < particles.length; i++) particles[i] = new Particle(random(width), random(height));
}

void draw() {
  background(255);

  float r;

  yoff = 0;
  for(int y = 0; y < rows; y++) {
    xoff = 0;
    for(int x = 0; x < cols; x++) {
      int index = x + y * cols;

      r = noise(xoff, yoff) * TWO_PI;

      v = PVector.fromAngle(r);

      flowfield[index] = v;

      pushMatrix();
      translate(x*scl + scl, y*scl);
      rotate(v.heading());
      stroke(0, 50);
      strokeWeight(1);
      line(0,0,scl,0);
      popMatrix();

      xoff += inc;
    }
    yoff += inc;
  }
  for (int i = 0; i < particles.length; i++) {
    particles[i].edges();
    particles[i].update();
    particles[i].show();
    particles[i].follow(flowfield);
  }
}

And the Particle class:

class Particle {
  PVector pos;
  PVector vel;
  PVector acc;
  float xpos, ypos;

  Particle(float x, float y) {
    pos = new PVector(x, y);
    vel = new PVector(0, 0);
    acc = new PVector(0, 0);
  }

  void follow(PVector[] vectors) {
    int x = floor(pos.x / scl);
    int y = floor(pos.y / scl);
    int index = x + y * cols;
    PVector force = vectors[index];
    applyForce(force);
  }

  void update() {
    vel.add(acc);
    pos.add(vel);
    acc.mult(0);
  }

  void applyForce(PVector force) {
    acc.add(force);
  }

  void show() {
    stroke(255,0,0);
    strokeWeight(5);
    point(pos.x, pos.y);
  }

  void edges() {
    if(pos.x < 0) pos.x = width;
    if(pos.x > width) pos.x = 0;
    if(pos.y < 0) pos.y = height;
    if(pos.y > height) pos.y = 0;
  }
}

Answers

  • Answer ✓

    index is 1231 sometimes, too big for vectors I guess

    you can keep it running by declining such events:

      void follow(PVector[] vectors) {
        int x = floor(pos.x / scl);
        int y = floor(pos.y / scl);
        int index = x + y * cols;
        println(index); 
        PVector force = new PVector(); 
        if (index<vectors.length&&index>=0) {
          force = vectors[index].copy();
        }
        applyForce(force);
      }
    

    but the cause is this line: int index = x + y * cols;

    maybe you are mixing up the position and the index of the thing?

Sign In or Register to comment.