Public
Edited
Feb 20, 2023
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
draw = (context) => {
const { objects, G } = context;
const stats = (context.stats = context.stats || {});
// update
for (let step = 1; step <= mutable speed.value; ++step) {
objects.forEach((a) => {
objects.forEach((b) => {
if (a === b) return;
let d = Math.abs(FastVector.distance(a.pos, b.pos));
// objects inside eachother have weakened gravity
if (d < a.r + b.r) d = (a.r + b.r) / 1.1;
let r2 = Math.pow(d, 2);
let f = (G * a.m * b.m) / r2;
let fa = b.pos.sub(a.pos).normalize().mul(f);
let fb = a.pos.sub(b.pos).normalize().mul(f);
// f = ma -> a = f/m
a.acc = a.acc.add(fa.div(a.m));
b.acc = b.acc.add(fb.div(b.m));
// console.log(fa);
});
});
// inertia
objects.forEach((obj) => {
obj.vel = obj.vel.add(obj.acc);
obj.pos = obj.pos.add(obj.vel);
obj.acc.x = 0;
obj.acc.y = 0;
// stats
if (!stats.min) stats.min = obj.pos.clone();
if (stats.min.x > obj.pos.x) stats.min.x = obj.pos.x;
if (stats.min.y > obj.pos.y) stats.min.y = obj.pos.y;
if (!stats.max) stats.max = obj.pos.clone();
if (stats.max.x < obj.pos.x) stats.max.x = obj.pos.x;
if (stats.max.y < obj.pos.y) stats.max.y = obj.pos.y;
if (!stats.r) stats.r = { min: obj.r, max: obj.r };
if (obj.r < stats.r.min) stats.r.min = obj.r;
if (obj.r > stats.r.max) stats.r.max = obj.r;
});
}
//
stats.dist = FastVector.distance(stats.max, stats.min);
let zoom = Math.sqrt(width * width + height * height) / stats.dist;
// zoom = Math.min(zoom, 1);
// zoom = Math.max(zoom, 0.5);

// render
p8g.colorMode(p8g.HSB);
p8g.background(0, 0, 0);
p8g.fill(0, 0, 100);

// draw objects
const minXY = Math.min(stats.min.x, stats.min.y);
const maxXY = Math.max(stats.max.x, stats.max.y);
objects.forEach((obj) => {
let x = map(obj.pos.x, minXY, maxXY, 0, width);
let y = map(obj.pos.y, minXY, maxXY, 0, height);
let r = zoom * obj.r;
p8g.ellipse(x, y, r, r);
});

// console.log(objects[0].pos);
// console.log(stats.dist);
}
Insert cell
setup = () => {
const objects = [];
let minS = 5;
let maxS = 10;
for (let i = 0; i < count; i++) {
let d = rand(1, 2);
let pos = new FastVector(
d * rand(-spread, spread),
d * rand(-spread, spread)
);
let vel = new FastVector(); // new FastVector(rand(-1, 1), rand(-1, 1));
let acc = new FastVector(rand(-0.3, 0.3), rand(-0.3, 0.3));
//
let s = rand(minS, maxS);
let m = Math.pow(10, s);
let r = map(s, 1, maxS, 1, 15);
objects.push({ pos, vel, acc, r, m });
}
objects.push({
pos: new FastVector(0, 0),
vel: new FastVector(),
acc: new FastVector(),
r: 20,
m: Math.pow(10, maxS + 2)
});
return { objects, G: 6.674 * Math.pow(10, -11) };
}
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