xxxxxxxxxx
63
// The Nature of Code
// Daniel Shiffman
// http://natureofcode.com
// Flow Field Following
class FlowField {
constructor(r) {
this.resolution = r;
//{!2} Determine the number of columns and rows.
this.cols = width / this.resolution;
this.rows = height / this.resolution;
//{!4} A flow field is a two-dimensional array of vectors. The example includes as separate function to create that array
this.field = new Array(this.cols);
for (let i = 0; i < this.cols; i++) {
this.field[i] = new Array(this.rows);
}
this.init();
}
// The init() function fills the 2D array with vectors
init() {
// Reseed noise for a new flow field each time
noiseSeed(random(10000));
let xoff = 0;
for (let i = 0; i < this.cols; i++) {
let yoff = 0;
for (let j = 0; j < this.rows; j++) {
//{.code-wide} In this example, use Perlin noise to create the vectors.
let angle = map(noise(xoff, yoff), 0, 1, 0, TWO_PI*2);
this.field[i][j] = p5.Vector.fromAngle(angle);
yoff += 0.1;
}
xoff += 0.1;
}
}
// Draw every vector
show() {
for (let i = 0; i < this.cols; i++) {
for (let j = 0; j < this.rows; j++) {
let w = width / this.cols;
let h = height / this.rows;
let v = this.field[i][j].copy();
v.setMag(w);
let x = i * w + w / 2;
let y = j * h + h / 2;
strokeWeight(1);
line(x, y, x + v.x, y + v.y);
strokeWeight(2);
point(x + v.x, y + v.y);
}
}
}
//{.code-wide} A function to return a p5.Vector based on a position
lookup(position) {
let column = constrain(floor(position.x / this.resolution), 0, this.cols - 1);
let row = constrain(floor(position.y / this.resolution), 0, this.rows - 1);
return this.field[column][row].copy();
}
}