I'm starting to learn how to DIY physics, and I have a question about implementing integration at the most basic level (i.e. this is not a Euler vs. RK4 question).
Nearly every example I come across has some integrate()
function which gets the timestep since the last update, and updates the acceleration (and/or velocity and/or position) since the last update.
In the simplest form: position += velocity * deltaTime
However, I don't understand why it's accumulated like this when it could just as easily be gotten by changing a function. For example: getPosition = makeNewFunction()
which could return something that has the signature of Time -> Position
, and the inner workings of that function are generated via the appropriate mathematical formula.
That way, there is no accumulation... whenever the position needs to be gotten, it calls that function with the current time.
My newbie understanding is that this would also avoid the errors that come from accumulation... so why does this not work, what am I missing?
(fwiw I did put together a basic proof of concept of this idea- though it's also testing a few other things at the same time so it's not the cleanest example: https://github.com/dakom/ball-bounce-frp)
EDIT 1: as mentioned in the comments, it's probably important to point out that I have not learned about changing acceleration yet, or dealing with jerk and other things that require higher-order integration than constant acceleration.
EDIT 2: here is some basic sample code of the idea, and pseudo javascript syntax - note that getKinematicPosition
is partially applied so it is returning a new function of just Time -> Position:
I'm sticking to position here but it could be something else, like getVelocity
, I guess...
getKinematicPosition = initialVelocity => acceleration => time =>
((.5 *acceleration) * (time * time)) + (initialVelocity * time);
getPosition = getKinematicPosition ([0,0,0]) (GRAVITY);
onTick = totalTime => {
position = getPosition (totalTime);
onCollision = () => {
getPosition = changeTheFunction(totalTime);
//changeTheFunction uses totalTime to base updates from 0
//it could use getKinematicPosition or something else entirely
}
}