Public
Edited
Jan 1, 2024
1 fork
Insert cell
Insert cell
Insert cell
{
replay;

const width = 600,
height = 200,
centerX = width / 2,
centerY = height / 2,
attractor = object({
mass: 20,
G: 1,
location: cm.vec(centerX, centerY)
}),
mover = object({
location: cm.vec(centerX, centerY - 50),
velocity: cm.vec(1, 0),
acceleration: cm.vec(),
mass: 5
}),
applyAttraction = attraction(attractor);

function update(app) {
app.append(cm.clear, { fill: cm.rgb(255) });

app
.datum(mover)
.process(cm.each, applyAttraction)
.process(cm.each, move)
.append(cm.circle, {
x: (d) => d.location.x,
y: (d) => d.location.y,
r: (d) => d.mass,
fill: cm.rgb(175),
stroke: "#000",
strokeWidth: 2
});

app
.datum(attractor) // Convert to an array.
.append(cm.circle, {
x: (d) => d.location.x,
y: (d) => d.location.y,
r: (d) => d.mass,
fill: cm.rgb(175),
stroke: "#000",
strokeWidth: 5
});
}

function dispose(app) {
invalidation.then(() => app.dispose());
}

function frame(app) {
app.node().style.border = "solid #000 1px";
}

return cm
.app({ width, height })
.on("update", update)
.call(dispose)
.call(frame)
.start()
.node();
}
Insert cell
function object(options) {
return {
location: cm.vec(),
velocity: cm.vec(),
acceleration: cm.vec(),
mass: 1,
aVelocity: 0,
aAcceleration: 0,
rotation: 0,
...options
};
}
Insert cell
function force(d) {
const callback = typeof d === "function" ? d : () => d;
return (d, ...params) => {
const f = callback(d, ...params);
if (f === null || f === undefined) return;
const a = cm.vecDiv(f, d.mass);
d.acceleration.add(a);
};
}
Insert cell
function move(d) {
d.velocity.add(d.acceleration);
d.location.add(d.velocity);
d.acceleration.mult(0);
}
Insert cell
function attraction(attractor) {
const { mass, G } = attractor;
return (d) => {
const dir = cm.vecSub(attractor.location, d.location);
const dist = cm.vecClamp(dir, 5, 25).mag();
const strength = (G * mass * d.mass) / (dist * dist);
const f = cm.vecMag(dir, strength);
const apply = force(f);
apply(d);
};
}
Insert cell
cm = require("@charming-art/charming@0.0.6")
Insert cell
import { quote } from "@pearmini/charming-shared"
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