Skip to content

Instantly share code, notes, and snippets.

@pushkine
Last active March 26, 2023 14:19
Show Gist options
  • Save pushkine/1b595fda102bec88e012c4e4c0cd6d1a to your computer and use it in GitHub Desktop.
Save pushkine/1b595fda102bec88e012c4e4c0cd6d1a to your computer and use it in GitHub Desktop.
Javascript spring solving algorithm. Solves real life damped harmonic oscillator physics equations as used in Apple iOS & many others. Tweak damping and stiffness for spring behavior, scale mass with value delta and set soft to force solution for a critically damped spring ( no bounce eased smooth ) . Play with this function's graph on www.desmo…
/** MIT License github.com/pushkine/ */
interface SpringParams {
mass?: number; // = 1.0
damping?: number; // = 10.0
stiffness?: number; // = 100.0
soft?: boolean; // = false
}
type seconds = number;
function solve_spring(from: number, velocity: number, to: number, params: SpringParams) {
const delta = to - from;
if (true === params.soft || 1.0 <= params.damping / (2.0 * Math.sqrt(params.stiffness * params.mass))) {
const angular_frequency = -Math.sqrt(params.stiffness / params.mass);
const leftover = -angular_frequency * delta - velocity;
return (t: seconds) => to - (delta + t * leftover) * Math.E ** (t * angular_frequency);
} else {
const damping_frequency = Math.sqrt(4.0 * params.mass * params.stiffness - params.damping ** 2.0);
const leftover = (params.damping * delta - 2.0 * params.mass * velocity) / damping_frequency;
const dfm = (0.5 * damping_frequency) / params.mass;
const dm = -(0.5 * params.damping) / params.mass;
return (t: seconds) => to - (Math.cos(t * dfm) * delta + Math.sin(t * dfm) * leftover) * Math.E ** (t * dm);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment