When animating a property of an object, I’d like the property to change slowly at first, then speed up and slow down at the end again.
For linear change, there is the lerp()
method in Processing PApplet
for linear interpolation between two values. I wonder if there is a method that could help me implement non-linear interpolation. I don’t have great theoretical knowledge of motion animation but I guess I’m looking for some interpolation technique. I’m not quite sure which one, though, and whether Processing has a support for that.
I know I could use the “easing” method (moving the object by a fraction of the outstanding travel distance every frame) which makes the object arrive slowly but it still does a jump start to a high speed.
As mentioned earlier, I’d like the object to start slow, then speed up and finish slow, which I realized can be represented by a negative and shifted cosine curve:
-cos(x) + 1 // for x in 0..TWO_PI
I implemented a function where I can use the above formula to calculate a point between start and end according to how many frames of animation has passed.
The downside of my approach is that I need to know the animation length (in frames) in advance, which might be unavoidable (is it?). Another thing that feels wrong is that for each point I need to calculate the amount of movement increments of all previous points and add them up. There must be an easier way (is there?).
My code is in Kotlin and I converted it into sudo code, hopefully everyone will understand.
val animationLength = 100 // in frames
val maxAccumulatedProgress = animationLength // I found that the sum of all increments mysteriously adds up to the animation length
fun interpolate(from: Float, to: Float, animationProgress: Int): Float {
// Add up increments for all previous animation frames
var accumulatedProgress = 0
repeat(animationProgress) {
val normalizedProgress = map(it, 0, animationLength, 0, TWO_PI)
val increment = formula(normalizedProgress)
accumulatedProgress += increment
}
return map(accumulatedProgress, 0, maxAccumulatedProgress, from, to)
}
fun formula(normalizedProgress: Float) = -1 * cos(normalizedProgress) + 1 }
Ideally, I’d just give the function the start
, end
and amt
between 0 and 1, same as to the lerp()
function. Is that possible and is there a built-in function in Processing to do that?