Public
Edited
Mar 4, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
flowField = {
const context = DOM.context2d(width, height);
let noiseZ = 0;

while (true) {
context.fillStyle = "white";
context.fillRect(0, 0, width, height);
// For each column
for (let column = 0; column < columns; column++) {
// For each row
for (let row = 0; row < rows; row++) {
let angle = n.simplex3(column / 50, row / 50, noiseZ) * Math.PI * 2; // a random direction
let length = n.simplex3(
column / 100 + 40000,
row / 100 + 40000,
noiseZ
);
context.save();
// translate to xxx column, xxx row
context.translate(size * (column - 1), size * (row - 1));

context.rotate(angle);

context.strokeStyle = "black";

context.beginPath();
context.moveTo(0, 0);
context.lineTo(0, size * length * 1.5);
context.stroke();
context.restore();
}
}

noiseZ += 0.004;
yield context.canvas;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
class Particle {
constructor(params) {
this.acceleration = p5Instance.createVector(0, 0);
this.velocity = P5.Vector.random2D();
this.position = p5Instance.createVector(width/2, height/2) // initial position
}

drivenByForce(context, x = 0, y = 0) {
this.acceleration.add(p5Instance.createVector(x, y));
this.velocity.add(this.acceleration);
this.position.add(this.velocity);

this.velocity.limit(2);

this.acceleration.setMag(0);
context.fillStyle = `hsla(50%, 50%, 50%, 1)`;
context.fillRect(this.position.x, this.position.y, 8, 8);
}

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
columnRowIndex = {
let particle = new Particle();
function roundAbs(x) {
return Math.floor(Math.abs(x));
}
let columnRowIndex = [
roundAbs(particle.position.x/ size),
roundAbs(particle.position.y / size)
];
return columnRowIndex;
}
Insert cell
Insert cell
Insert cell
flowFieldDataDemo = {
let flowField = new Array(columns);
let noiseZ = 0.004;

for (let column = 0; column < columns; column++) {
flowField[column] = new Array(rows)
// For each row
for (let row = 0; row < rows; row++) {
let angle = n.simplex3(column / 50, row / 50, noiseZ) * Math.PI * 2; // a random direction
let length = n.simplex3(column / 100 + 40000, row / 100 + 40000, noiseZ);
flowField[column][row]=[angle, length]
}
}

return flowField;
}
Insert cell
{
const [columnIndex, rowIndex] = columnRowIndex

return flowFieldDataDemo[columnIndex][rowIndex]
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
flowFieldParticleWithBound = {
function roundAbs(x) {
return Math.floor(Math.abs(x));
}

const context = DOM.context2d(width, height);

let particle = new Particle();

let flowField = new Array(columns).fill(1);
let noiseZ = 0.004;

while (true) {
// For each column
for (let column = 0; column < columns; column++) {
flowField[column] = new Array(rows).fill(1);
// For each row
for (let row = 0; row < rows; row++) {
let angle = n.simplex3(column / 50, row / 50, noiseZ) * Math.PI * 2; // a random direction
let length = n.simplex3(
column / 100 + 40000,
row / 100 + 40000,
noiseZ
);
flowField[column][row] = [angle, length];
}
}
let acc =
flowField[roundAbs(particle.position.x / size)][
roundAbs(particle.position.y / size)
];
// context.clearRect(0, 0, width, height);
context.save();

particle.drivenByForce(context, ...acc);

particle.goBackToField();

context.restore();
noiseZ += 0.004;

yield context.canvas;
}
}
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