Last active
April 15, 2018 12:44
-
-
Save haxiomic/2e40d6f407eca8188ede006e4b27635d to your computer and use it in GitHub Desktop.
Analytic spring integration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// analyitc spring integration | |
// useful when you want a robust single-spring simulation | |
stepSpring( | |
dt_s: number, | |
state: { | |
x: number, | |
v: number, | |
pe: number, // potential energy | |
}, parameters: { | |
tension: number, | |
friction: number, | |
}) { | |
// analytic integration (unconditionally stable) | |
// references: | |
// http://mathworld.wolfram.com/OverdampedSimpleHarmonicMotion.html | |
// http://mathworld.wolfram.com/CriticallyDampedSimpleHarmonicMotion.html | |
let k = parameters.tension; | |
let f = parameters.friction; | |
let t = dt_s; | |
let v0 = state.v; | |
let x0 = state.x; | |
let critical = k * 4 - f * f; | |
if (critical === 0) { | |
// critically damped | |
let w = Math.sqrt(k); | |
let A = x0; | |
let B = v0 + w * x0; | |
let e = Math.exp(-w * t); | |
state.x = (A + B * t) * e; | |
state.v = (B - w * (A + B * t)) * e; | |
} else if (critical <= 0) { | |
// over-damped | |
let sqrt = Math.sqrt(-critical); | |
let rp = 0.5 * (-f + sqrt); | |
let rn = 0.5 * (-f - sqrt); | |
let B = (rn * x0 - v0) / (rn - rp); | |
let A = x0 - B; | |
let en = Math.exp(rn * t); | |
let ep = Math.exp(rp * t); | |
state.x = A * en + B * ep; | |
state.v = A * rn * en + B * rp * ep; | |
} else { | |
// under-damped | |
let a = -f/2; | |
let b = Math.sqrt(critical * 0.25); | |
let phaseShift = Math.atan(b / ((v0/x0) - a)); | |
let A = x0 / Math.sin(phaseShift); | |
let e = Math.exp(a * t); | |
let s = Math.sin(b * t + phaseShift); | |
let c = Math.cos(b * t + phaseShift); | |
state.x = A * e * s; | |
state.v = A * e * (a * s + b * c); | |
} | |
state.pe = 0.5 * k * state.x * state.x; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment