views:

255

answers:

4

I've been trying to solve this problem for a number of days now but I must be missing something.

Known Variables:
vi = Initial Velocity
t = Animation Duration
d = Distance.
end velocity should always be zero

The function I'm trying to create: D(0...t) = the current distance for a given time

Using this information I want to be able to create a smooth animation curve with varying velocity (ease-in/ease-out).

The animation must be able ease-in from an initial velocity.

The animation must be exactly t seconds and must be travel exactly d units.

The curve should lean towards the average velocity with acceleration occurring at the beginning and the end portions of the curve.

I'm open to extra configuration variables.

The best I've been able to come up with is something that doesn't factor in the initial velocity. I'm hoping someone smarter can help me out. ;)

Thank you!

p.s. I'm working with an ECMAScript variant

+1  A: 

I believe you want to solve your problem in 3 parts.

First, you need to solve for the minimum velocity necessary to complete the distance in time T.

This would be pretty simple (D/t) = v(min)

It assumes instantaneous acceleration from v(initial) to v(min) and again deceleration over a time period of 0s at the beginning and end.

so for example say your v(i) is 5px/s. you want a 100px movement over 10 seconds.

v(min) = 100px/10s = 10px/s

Second, you want a smooth acceleration from v(initial) to v(min). this will take some period of time t(acc). Assuming the acceleration and deceleration will be equal, then you can just figure for one of them, then multiply by 2. We can call the function that describes the distance travelled during accelleration D(accel).

Lets keep it easy to start and say we want the duration of accelleration to be 1s

so your equation for total distance travelled is going to be D(total) = D(accel) + D(v(max) )

When you know that D(accel) is for 2s total, you can calculate

D(accel) = ( V(ini) + V(max) ) /2) * (2seconds)

and

D(v(max)) = V(max) * 8s

solving for V(max) we get

100px = D(accel) + D(v(max))

100px = ( 5px/s + VMax) /2 *(2s)) + VMax *8s

100px = 5px + (Vmax * 1s) + Vmax *8s

95px = 9Vmax *s

VMax = 95px/9s

VMax = 10.556px/s

You can now go back and replace your 1s acceleration window with a formula that defines the acceleration window as a % of the overall time period or some other thing.

Also note that for animation purposes, you will have to break 10.556px/s down into per frame px movements and account for time appropriately.

Zak
please somebody edit my confusing use of VMAX and v(max) for clarity.. I have to run!
Zak
Alos note, I guess you never really need v(min) i just calculate it to ensure my v(max) is sane and greater than v(min)
Zak
A: 

Using constant accelerations:

Definitions:

Vi - Initial velocity
Va - Average velocity
Vo - Ending velocity
D  - Total distance to be traveled
T  - Total time for travel
t1 - Acceleration time from beginning to Va
t2 - Acceleration time from Va to Vo

The equation to solve is:

(Vi+Va)/2*t1 + Va*(T-t2-t1) + (Va+Vo)/2*t2 = D

You should decide how much time the initial acceleration (t1) and the final acceleration (t2) takes and then you are left with only one unknown -> Va, which can be easily solved.

EDIT: find the distance as a function of time:

Well, now that you know the velocities, it is easy to figure out the distance traveled:

D(t) = Vi*t + 0.5*t^2*(Va-Vi)/t1                {0<t<t1}
D(t) = Va*(t-t1) + D1                           {t1<t<t3}
D(t) = Va*(t-t3)+0.5*(t-t3)^2*(Vo-Va)/t2 + D2   {t3<t<T}

where t3=(T-t2), D1 and D2 are the distance traveled at the end of the first and second segments, which can be found from the respective functions:

D1 = 0.5*(Va+Vi)*t1
D2 = D1 + Va*(t3-t1)

EDIT 2: Solving for Va:

(Vi+Va)/2*t1 + Va*(T-t2-t1) + (Va+Vo)/2*t2 = D

Remember that t1 and t2 are the problem parameters that you choose. You decide what fraction of the movement the object accelerates and decelerates. Let's say t1=t2=0.1*T. Substitution then gives:

(Vi+Va)/2*(0.1T) + Va*(T-(0.1T)-(0.1T)) + (Va+Vo)/2*(0.1T) = D
Va*(0.1T/2 + T-0.1T-0.1T + 0.1T/2) + Vi*(0.1T)/2 + Vo*(0.1T)/2 = D
Va*(0.9T) + Vi*(0.05T) + Vo*(0.05T) = D
Va*(0.9T) = D - Vi*(0.05T) + Vo*(0.05T)
Va = (D - (Vi + Vo)*(0.05T)) / (0.9T)

Got it?

ysap
I need to be able to know D for 0...T. This just gets me to a value I knew at the start. Thanks for replying.
abustin
[how to prevent comments from killing the formatting of the text???]Well, now that you know the velocities, it is easy to figure out the distance traveled:******* D(t) = Vi*t + 0.5*t^2*(Va-Vi)/t1 {t<t1}******* D(t) = Va * (t-t1) + D1 {t1<t<t3}******* D(t) = Va*(t-t3)+0.5*(t-t3)^2*(Vo-Va)/t2 + D2 {t2<t<T}*******where t3=(T-t2), D1 and D2 are the distance traveled at the end of the first and second segments, which can be found from the respective functions:******* D1 = 0.5*(Va+Vi)*t1******* D2 = D1 + Va*(t3-t1)*******
ysap
@ysap - thanks for the update, i'll try it out in the next 24 and let you know how it goes :).
abustin
@ysap - "Va, which can be easily solved" - hmmm, any hints? ;) I'm having problems figuring it out.
abustin
A: 

abustin, since you don't like the 3 segment solution, you may want to try looking at Bezier curves to solve this problem. Bezier curve can be utilized to interpolate time as well as distance, so you can define a few control points near the ends of your motion to generate acceleration, where the middle "segment" will be defined such that the velocity is close to constant. Utilizing splines is a possibility too.

ysap
I was thinking about the same. I've used cubic bezier paths for non linear animation before, it would be interesting to use it to solve this problem.
abustin
+2  A: 

Here is a different solution, where there isn't any time interval where the velocity is constant. Instead, velocity as a function of time is a second-order polynomial, and the acceleration is linear in time (positive at the beginning, and negative at the end). Maybe you can try it.

Let me rename your variables a bit. Let

  • T = final time = animation duration
  • V = initial velocity (>0)
  • D = total distance (>0)

We are searching for a smooth function v(t) (velocity as a function of time) such that:

  • v(0) = V
  • v(T) = 0
  • the integral from 0 to T of v(t)dt is D

With a (concave) second-order polynomial we can satisfy all the three constraints. Hence, let

v(t) := at^2 + bt + c

and let's solve for a, b, c. The first constraint v(0) = V gives immediately c = V. The second constraint reads

aT^2 + bT + V = 0

On the other hand, the integral of v(t) is d(t) = 1/3 a t^3 + 1/2 b t^2 + Vt (this is the distance covered up to time t), hence the third constraint reads

d(T) = 1/3 a T^3 + 1/2 b T^2 + VT = D

The last two equations seem messy, but they are just two linear equations in the two unknowns a, b, and they should be easily solvable. If I did my computations correctly, the final result is

a = 3V/T^2 - 6D/T^3, b = 6D/T^2 - 4V/T

If you substitute a, b, c in the expression of d(t), you obtain the covered distance as a function of time.

Federico Ramponi