Public
Edited
Aug 8, 2023
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
grid: false,
width: width * 0.9,
height: width < 600 ? 500 : 500,
style: {
background: `black`,
color: `white`,
padding: `1rem`,
overflow: `visible`
},
x: {
domain: [0, 100],
label: "Time"
},
y: {
domain: [-100, 100],
label: "Position"
},
color: {
scheme: "inferno",
domain: [-1, 3],
reverse: false,
clamp: true
},
marks: [
Plot.line(particle_field, {
x: "time",
y: "position",
z: "index",
stroke: "speed"
})
]
})
Insert cell
d3.extent(particle_field, (d) => d.velocity)
Insert cell
grouped = d3.flatGroup(particle_field, (d) => d.index)
Insert cell
particle_field = {
const out = [];

for (const [index, initial_position] of initial_positions.entries()) {
const initial = Particle({
index,
time: 0,
position: initial_position,
velocity: 0,
mass: 1
});
let previous = initial;
for (const time of time_steps) {
const dt = time - previous.time;
const distance_to_planet = Math.abs(previous.position - planet.position);
if (distance_to_planet < planet_radius) continue;
const acceleration = gravity(previous, planet);
const velocity_delta = acceleration * dt;
let velocity = previous.velocity + velocity_delta;
const speed = Math.abs(velocity);
const position_delta = velocity * dt;
const position = previous.position + position_delta;
const next = Particle({
index,
time,
position,
velocity,
speed,
mass: initial.mass,
data: {
distance_to_planet
}
});
previous = next;
out.push(next);
}
}

return out;
}
Insert cell
planet = Particle({
index: 9999,
time: 0,
position: 27.34,
velocity: 0,
mass: planet_mass_base * 10 ** planet_mass_exponent
})
Insert cell
function Particle({ index, time, position, velocity, speed, mass, data }) {
return {
index,
time,
position,
velocity,
speed,
mass,
data
};
}
Insert cell
time_steps = d3.range(0, 100, 0.4)
Insert cell
initial_positions = d3
.range(number_of_particles)
.map((index) =>
d3.scaleLinear([0, number_of_particles - 1], [-100, 100])(index)
)
Insert cell
function gravity(body_a, body_b) {
const delta = body_b.position - body_a.position;
const distance = Math.abs(delta);
const distance_squared = distance ** 2;
const magnitude = (body_a.mass * body_b.mass) / distance_squared;
const sign = Math.sign(delta);
return sign * magnitude;
}
Insert cell
Matter = (await import("https://cdn.skypack.dev/matter-js")).default
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