Springy.js
Created on 2021-01-18T18:16:07-06:00
Stores graph as a list of nodes and a list of edges.
Short version of what happens:
Coulomb's law pushes elements which are on top of one another away.
Hookes' law pulls (or pushes) elements that should be near one another via spring physics.
Parameters for the solver:
- stiffness: how stiff springs are
- repulsion: how strongly nodes push away from one another
- damping: a moderator where nodes lose speed while traveling
- minimum energy threshold: if total energy in the graph goes below this then solving stops
- maximum speed: maximum speed a node can travel
- timestep: 0.03 in orignal; controls how many seconds are run in each simulation step
Coulomb's Law
Run on a pairwise list of nodes.
d <- point1 - point2 distance <- magnitude(d) + 0.1 distance2 <- distance^2 direction <- normalize(d) applyForce(point1, (direction * repulsion) / (distance2 * 0.5)) applyForce(point2, (direction * repulsion) / (distance2 * -0.5))
- 0.1 is added to distance to avoid math blowing up near zero
Hookes Law
Run on each spring.
d <- point2 - point1 displacement <- spring.length - magnitude(d) direction <- normalize(d) applyForce(point1, direction * (spring.k * displacement * -0.5)) applyForce(point2, direction * (spring.k * displacement * 0.5))
- 0.1 is added to distance to avoid math blowing up near zero
Attract to Center
Run on each node.
direction <- -point.p applyForce(point.p, direction * (repulsion / 50.0))
Updating Velocity
Run on each node.
point.v <- (point.v + (point.a * timestep)) * this.damping if magnitude(point.v) > maxSpeed: point.v <- normalize(point.v) * maxSpeed point.a = (0, 0)
Had a developer remark about if this (and update position) are the only places the integration code exists.
Applying force
a <- a + (force / mass)
Updating Position
Run on each node.
point.p <- point.p + (point.v * timestep)
Had a developer remark about if this (and update velocity) are the only places the integration code exists.
Calculating total energy
Sum this formula over all nodes:
speed <- magnitude(point.v) energy <- 0.5 * point.m * speed^2
Laying out the graph
Repeat until the total energy in the system is below some cutoff:
<< Coulomb's Law >> << Hookes Law >> << Attract to Center >> << Updating Velocity >> << Updating Position >>