Public
Edited
May 9, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
canvas = {
const context = DOM.context2d(width, height);
context.fillStyle = "black";
context.fillRect(0, 0, width, height);
let step = 0;
let color = muzli[Palette];
// let color = "black"
let flow_Field = generateFlowfield();

let particles = [];
for (let i = 0; i < num_particle; i++) {
particles.push(new Particle(color[randInt(0, 5)]));
}
let noiseZ = 0;

while (step < num_steps) {
generateFlowfield(0);
step++;
context.globalCompositeOperation = "lighter";
context.save();

particles.forEach((p) => {
// p.getForce(flow_Field);
p.applyForce(flow_Field);
p.receiveForceAndUpdatePosition();
p.show(context, color);
p.goBackToField();
});

context.restore();

noiseZ += 0.01;
yield context.canvas;
}
}
Insert cell
Insert cell
Insert cell
class Particle {
constructor(color) {
this.acceleration = p5Instance.createVector(0, 0);
this.velocity = P5.Vector.random2D();
this.position = p5Instance.createVector(
Math.random() * width,
Math.random() * height
);
this.color = color;
}

// what do I want to happen once there is a particle in the flow field

getForce(flowfield) {
// console.log(flowfield);
return flowfield[roundAbs(this.position.x / size)][
roundAbs(this.position.y / size)
];
}
applyForce(flowfield) {
let forceVector = this.getForce(flowfield);
this.acceleration.add(forceVector);
}

receiveForceAndUpdatePosition() {
this.velocity.add(this.acceleration);
this.position.add(this.velocity);

this.velocity.limit(max_speed);

this.acceleration.setMag(0);
}

show(context) {
// let color = this.color[randInt(0, 5)];
// let color = "black";
context.beginPath();
context.globalAlpha = 0.1;
context.arc(this.position.x, this.position.y, 1.2, 0, 2 * Math.PI);
context.fillStyle = this.color;
context.fill();
// context.strokeStyle = color;
// context.stroke();
}
goBackToField() {
if (this.position.x > width) {
this.position.x = 0;
} else if (this.position.x < -size) {
this.position.x = width - 1;
}
if (this.position.y > height) {
// this.position.y = 0;
} else if (this.position.y < -size) {
this.position.y = height - 1;
}
}
}
Insert cell
Insert cell
f = new Array(columns)
Insert cell
function generateFlowfield(noiseZ = 0) {
let flow_Field = new Array(columns);
for (let col = 0; col < columns; col++) {
flow_Field[col] = new Array(rows);

for (let row = 0; row < rows; row++) {
let angleNoise =
p5Instance.noise(
col / noise_step_magnitude,
row / noise_step_magnitude,
noiseZ
) *
Math.PI *
2;
let angleVector = P5.Vector.fromAngle(angleNoise, step_strength);
flow_Field[col][row] = angleVector;
}
}
return flow_Field;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more