Flow Field (Perlin noise)"Array Index Out Of Bounds Exception" Error

Hi everyone, I try to convert Coding Challenge #24: Perlin Noise Flow Field to processing,But encountered “ArrayIndexOutOfBoundsException” Error,This is my code:

float inc = 0.1;
int scl = 20;
int cols, rows;

float zoff = 0;

ArrayList <Particle> particles;
PVector [] flowfield;

void setup() {
  size(800, 800);
  pixelDensity(2);
  smooth();
  background(0);

  cols = width / scl;
  rows = height / scl;

  particles = new ArrayList <Particle> ();
  flowfield = new PVector [cols * rows];

  for (int i = 0; i < 100; i++) {
    particles.add(new Particle());
  }
}

void draw() {

  stroke(255);

  float yoff = 0;

  for (int y = 0; y < rows; y++) {
    float xoff = 0;
    for (int x = 0; x < cols; x++) {
      int index = int(x + y * cols);
      float angle = noise(xoff, yoff, zoff) * TWO_PI * 4;
      PVector v = PVector.fromAngle(angle);
      v.setMag(1);
      flowfield[index] = v;

      xoff += inc;
    }
    yoff += inc;
    zoff += 0.001;
  }

  for (int i = 0; i < particles.size(); i++) {
    Particle p = particles.get(i);
    p.run();
    p.fllow(flowfield);
  }
}

class Particle {
  PVector pos;
  PVector vel;
  PVector acc;
  float maxspeed;
  PVector prevPos;

  Particle() {
    pos = new PVector(random(width), random(height));
    vel = new PVector(0, 0);
    acc = new PVector(0, 0);
    maxspeed = 2;
    prevPos = pos.copy();
  }

  void run() {
    update();
    display();
    edges();
  }

  void fllow(PVector [] v) {
    int x = floor(pos.x / scl) + 1;
    int y = floor(pos.y / scl) + 1;
    int index = int(x + y * cols);

    PVector force = v[index];
    applyForce(force);
  }

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

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

  void display() {
    stroke(255, 10);
    line(pos.x, pos.y, prevPos.x, prevPos.y);
  }

  void updatePrev() {
    prevPos.x = pos.x;
    prevPos.y = pos.y;
  }

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

I think the problem lies in the “flowfield” section, but I still can’t find a solution, thank you very much.

1 Like

there are some issues with your code but this will get you up and running until you discover them. in the fflow method you are calculating the x and y incorrectly and you can work out why that is but if you change this

  void fllow(PVector [] v) {
    int x = floor(pos.x / scl) + 1;
    int y = floor(pos.y / scl) + 1;
    int index = int(x + y * cols);

to this

  void fllow(PVector [] v) {
    int x = floor(pos.x / scl) + 1;
    int y = floor(pos.y % scl) + 1;
    int index = int(x + y * cols);

it will run

1 Like

The program is ready to run, I think I don’t know enough about arrays, thank you very much for your help!