Public
Edited
Jan 13, 2024
Fork of Arcsteps
Insert cell
Insert cell
ellipseFlight(trajectory(step_conf, randNum))
Insert cell
ellipseFlight = ({coords, pathstring}) => {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
var orbit = svg.append("g")
.append("path")
.attr("fill", "none")
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("d", pathstring);
var masses = svg.append("g")
.selectAll("circle").data(coords)
.enter().append("circle")
.attr("r", function(d) { return randNumGen(2, 8); })
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("fill", "black");
return svg.node();
}
Insert cell
trajectory(step_conf, randNum)
Insert cell
Insert cell
margin = ({top: 10, right: 10, bottom: 10, left: 10})
Insert cell
height = 512
Insert cell
scalex = (num_jumps) => d3.scaleLinear()
.domain([-num_jumps*step_conf.max, num_jumps*step_conf.max])
.range([margin.left, width - margin.right])
Insert cell
scaley = (num_jumps) => d3.scaleLinear()
.domain([-num_jumps*step_conf.max, num_jumps*step_conf.max])
.range([height - margin.bottom, margin.top])
Insert cell
Insert cell
step_conf = ({min: 20, max: 40, drunk: true, rand_rot: true, rmin: 50, rmax: 130})
Insert cell
randNum = {
while (true) {
await Promises.delay(1000)
yield randNumGen(3, 7)
}
}
//randNum = randNumGen(2, 6)
Insert cell
trajectory = (step_conf, number) => {
const coords = delta2coords(rel_coords(step_conf.min, step_conf.max, step_conf.drunk, number))
const scaled_coords = coords.map((d) => ({x: scalex(number)(d.x), y: scaley(number)(d.y)}))
const pathstring = allTheEllipsesString(scaled_coords,
() => randNumGen(step_conf.rmin, step_conf.rmax),
() => randNumGen(step_conf.rmin, step_conf.rmax),
() => randNumGen(0, 360),
() => Math.round(Math.random()),
() => Math.round(Math.random()))
return {coords: scaled_coords, pathstring: pathstring}
}
Insert cell
delta2coords = (deltas) => {
let trajectory = [{x: 0, y: 0}]
deltas.reduce( (prev, curr, i) => trajectory[i] = {x: prev.x + curr.x, y: prev.y + curr.y} )
return trajectory
}
Insert cell
rel_coords = (min, max, drunk, number, origin={x: 0, y: 0}) => {
return ([origin, ...Array.from({length: number - 1}, () => jump(min, max, drunk))])
}
Insert cell
jump = (min, max, drunk) => {
const drunkStep = drunk === false ? 1 : ( Math.random() > 0.5 ? 1 : -1 )
const coord = {x: drunkStep*randNumGen(min, max), y: drunkStep*randNumGen(min, max)}
return (coord)
}
Insert cell
randNumGen = (min, max) => Math.round(Math.abs(min + (max - min)*Math.random()))
Insert cell
Insert cell
/**
* Accumulate individual elliptical arcs for coords
* with random generators for rotation, large-arc-flag and sweep-flag
**/
allTheEllipsesString = (coords, rx_func, ry_func, rot_func, laf_func, sf_func) => {
let pathString = "M" + coords[0].x + "," + coords[0].y
for (let i = 1; i < coords.length; i++) {
pathString = pathString + ellipseString(rx_func(), ry_func(), rot_func(), laf_func(), sf_func(), coords[i])
}
return pathString
}
Insert cell
/**
* Creates an elliptical path between p1 and p2, randomly choosing large-arc-flag and sweep-flag
* TODO mimic one of these being at a focus
**/
ellipseString = (rx, ry, rotation, laf, sf, p2) => {
return " A" + rx + "," + ry + " " + rotation + " " + laf + "," + sf + " " + p2.x + "," + p2.y
}
Insert cell
init_traj = ({coords: [{x: 0, y: 0}], pathstring: "M0,0"})
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