Created
February 3, 2015 22:50
-
-
Save debreuil/95de1292289166e16e3a to your computer and use it in GitHub Desktop.
Pixate spring implementation
This file contains 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
// Evaluates one tick of a spring using the Runge-Kutta Algorithm. | |
// This is generally a bit mathy, here is a reasonable intro for those interested: | |
// http://gafferongames.com/game-physics/integration-basics/ | |
// (double)stepSize: the duration between steps. This should be around 1/60th of a second. Values too large will not work as the spring adjusts itself over time based on previous values, so if values are larger than 1/60th of a second this method should be called for each whole 1/60th of a second segment plus the remainder. | |
// external variables | |
// (double) _curT: How far along the spring the current value is, 0 being start and 1 being end. Because this is a spring that value will go beyond 1 and then back below 1 etc, as it 'springs'. | |
// (double) _tVelocity: the current velocity of the spring. | |
// (BOOL) _stopSpring: indicates the spring has settled to minimum amount and should be considered the last 'tick' | |
- (void)evaluateRK:(double)stepSize | |
{ | |
double x = _curT - 1; | |
double v = _tVelocity; | |
double aDx = v; | |
double aDv = [self accelerateX:x vel:v]; | |
double bDx = v + aDv * (stepSize * 0.5); | |
double bDv = [self accelerateX:x + aDx * (stepSize * 0.5) vel:bDx]; | |
double cDx = v + bDv * (stepSize * 0.5); | |
double cDv = [self accelerateX:x + bDx * (stepSize * 0.5) vel:cDx]; | |
double dDx = v + cDv * stepSize; | |
double dDv = [self accelerateX:x + cDx * stepSize vel:dDx]; | |
double dxdt = 1.0 / 6.0 * (aDx + 2.0 * (bDx + cDx) + dDx); | |
double dvdt = 1.0 / 6.0 * (aDv + 2.0 * (bDv + cDv) + dDv); | |
double aftX = x + dxdt * stepSize; | |
double aftV = v + dvdt * stepSize; | |
_curT = 1 + aftX; | |
double finalVelocity = aftV; | |
double netFloat = aftX; | |
double net1DVelocity = aftV; | |
double netValueIsLow = fabs(netFloat) < _tolerance; | |
double netVelocityIsLow = fabs(net1DVelocity) < _tolerance; | |
_tVelocity = finalVelocity; | |
// never turn spring back on | |
if(!_stopSpring) | |
{ | |
_stopSpring = netValueIsLow && netVelocityIsLow; | |
} | |
} | |
- (double) accelerateX:(double)x vel:(double)v | |
{ | |
return -_tensionValue * x - _frictionValue * v; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment