In my previous post, I mentioned looking for a polynomial for an application. I am working on an application that involves clicking or dragging tiles around. Once you release the tile, I want it to snap to where it's supposed to be.
The easiest way to do this is to just warp it to where it's supposed to go. This isn't very visually pleasing. The next best thing is to set up a time-interval on which it moves into place. Then, linearly interpolate from where it is to where it's going (here with t normalized to range between zero and one):
That's much better than just warping, but it doesn't have any sort of fade-in or fade-out. It instantaneously has its maximum velocity and then instantaneously stops at the end.
Typically, then one uses a cubic spline to scale the t value before interpolating to get a speed up in the beginning and then slow down in the end.
I might like to decelerate faster than I accelerate though so I might employ a fancier (higher-order) polynomial like:
But, in this case, I wanted the tile to overshoot the target a bit and then nestle/wiggle into place. So, I experimented with a bunch of different polynomials. I was having real trouble getting them to behave in a way that felt right. So, I went back to the physics of it.
What I wanted was pretty similar to damped spring motion. Imagine
you've tied a heavy weight to a spring and suspended it all in a jar
of oil. If you perturb the weight, it will bounce up and down but
each bounce is closer to the equilibrium point than the previous bounce.
(Actually, it's more complicated than that. If the spring is too weak
or the oil too viscous, the weight will just slowly return to the
equilibrium point without ever going past it. That's called
harmonic oscillation. What I want is called
harmonic oscillation and that's
all I will concern myself with here.) The equation for this
To get it to wiggle an appropriate amount, I was using ω = 4π and with a φ of -π/2 effectively making the cosine into a sine.
This is all well and good, but to really scale my t, I need this to start at zero and approach one. So, I was really using:
Well, now it starts zig-zagging on the way to its destination. It already starts cutting back long before it makes it to where it's going. So, I needed to get close to the destination much sooner. So, I jiggered the t term:
This looks terrible though. I hit the destination is less than a tenth of a second and then not again until about half a second. The reason for this is that the oscillations happen at a fixed rate. ω never changes and t moves steadily along so that sin(ωt) keeps the same frequency throughout my interval. So, I jiggered the t going into the sine function to make my oscillations start out slowly and really speed up toward the end.
This is much better, but it still didn't give the feeling of settling in because the second oscillation was almost as high as the first. So, I could up the value of k and get somewhere. But, I wanted it to be even more dramatic. So, I changed the t in the exponent to t3 (and used a slightly higher k: was 3 and is now 4):
This was pretty decent, but I felt the initial attack was a bit strong. So, I dropped down the exponent on my base curve from 4 to 2:
And, this is pretty nice. It looks pretty natural (despite making an entire
mess out of damped harmonic motion). It doesn't ease in at all though
so I might still need to replace the 1 - (1-t)2 with something
of a higher order. But, I might not mind the tile achieving instant
velocity. It gives it that
I'm really supposed to be over there
sort of urgency.