SketchBook

var nx = 100;
var ny = 100;
var p = [];
var v = [];
var time;

var parts = [];
var N = 3000;
var zoff;

function setup() {
createCanvas(windowWidth,
windowHeight);

colorMode(HSB, 360, 100, 100, 255);
field(random(0, 100),
random(120, 200));

for (var i = 0; i < N; i = i + 1) {
parts[i] = {
x: random(-100, width + 100),
y: random(-100, height + 100),
pX: 0.0,
pY: 0.0,
vx: 0.0,
vy: 0.0
};

parts[i].pX = parts[i].x;
parts[i].pY = parts[i].y;
}

time = 0.0;
}

function draw() {
background(0, 0, 100, 5);

var fx, fy, ix, iy, t, s;
var tmp1, tmp2, X, Y;
var H, S, B, A;

for (var i = 0; i < N; i = i + 1) {
fx = (parts[i].x * nx) / width;
fy = (parts[i].y * ny) / height;

ix = parseInt(fx);
iy = parseInt(fy);
ix = constrain(ix, 1, nx - 2);
iy = constrain(iy, 1, ny - 2);

t = fx - ix;
s = fy - iy;

X = interp(v[ix ][iy ].x,
v[ix + 1][iy ].x,
v[ix ][iy + 1].x,
v[ix + 1][iy + 1].x,
t, s);

Y = interp(v[ix ][iy ].y,
v[ix + 1][iy ].y,
v[ix ][iy + 1].y,
v[ix + 1][iy + 1].y,
t, s);

parts[i].vx = 3.0 * X;
parts[i].vy = 3.0 * Y;

parts[i].x += parts[i].vx;
parts[i].y += parts[i].vy;

H = 180 * p[ix][iy] + 0.5 * time;
S = 80 + (1 / 3) * time;
B = 80 + 20 * p[ix][iy];
A = 50;

H += 120;

stroke(H, S, B, A);
line(parts[i].pX, parts[i].pY,
parts[i].x, parts[i].y);

if (
parts[i].x < 0 ||
parts[i].x > width ||
parts[i].y < 0 ||
parts[i].y > height
) {
resetParticle(parts[i]);
}

parts[i].pX = parts[i].x;
parts[i].pY = parts[i].y;
}

time = time + 1;

if (time > 300) {
background(0, 0, 100, 50);
field(random(0, 100),
random(120, 200));
time = 0;
}
}

function interp(a, b, c, d, t, s) {
tmp1 = (1 - t) * a + t * b;
tmp2 = (1 - t) * c + t * d;
return (1 - s) * tmp1 + s * tmp2;
}

function resetParticle(p) {
p.x = random(-100, width + 100);
p.y = random(-100, height + 100);
}

function field(zoff, sc) {
var x, y;
var nx1 = nx + 1;
var ny1 = ny + 1;
for (x = 0; x < nx1; x++) {
p[x] = [];
for (y = 0; y < ny1; y++) {
p[x][y] = noise(x / sc,
y / sc,
zoff);
}
}

for (x = 1; x < nx; x++) {
v[x] = [];
for (y = 1; y < ny; y++) {
v[x][y] = {
x: p[x][y + 1] - p[x][y],
y: -(p[x + 1][y] - p[x][y])
};

var xx = v[x][y].x * v[x][y].x;
var yy = v[x][y].y * v[x][y].y;
var L = sqrt(xx + yy);
v[x][y].x /= L;
v[x][y].y /= L;
}
}
}