[Closed] Calculating acceleration
My problem is that I have no idea how to find the derivative of the position function in 3ds Max!
Try getting it for rational-bezier curves, to allow overshooting at the ends! With cubic curves it isnt to hard – thats the angle im looking at this, getting the tangency along it uniformly, and then using t as a magnitude for the normalize vector at the ends.
So if we treat it as a curve, either non-uniform or uniform its a little easier.
Anyway yeah its complex, and dynamics is my least strong area – would love to work on some dynamics and talk mork about this stuff with you
Hi!
I just found this thread since im dealing with that kind of matter myself (although im not really concerned with my accurarcy atm) since yesterday and wanted to comment on the approaches here.
Let’s imagine a car runs at frame 1 with 100 kilometers/hour and linearly decellerates to 0 kilometers/hour at frame 100, then at frame 100 the velocity is per definition exactly 0.
If we take a look at eek’s code, the 100th entry in the array would yield the sum of the distances of the steps(which get linearly smaller but never negative) divided by 100 frames.
But this will never yield 0, even if the framenumbers got much higher, so this approach as i understand it would be incorrect.
I think d3coy’s idea is evenly accurate throughout the whole trajectory while eek’s formula would just wash out at high framecounts.
The only possibility to increase the accuracy of the velocity would be to make the time-intervals (and with that the segments of the trajectory) smaller.
I don’t know how far max interpolates on a subframe scale, but if it does so, the following might work more or less accurate:
velocity=#();
timeinterval=1 –time-interval-length in units of ticks
for f=1 to 100 do (
thetime=f*ticks_per_frame; –timevalue in the measure of ticks
t1= at time thetime obj.pos
t2= at time (thetime-timeinterval) obj.pos – position at thetime minus 1 tick
t3= at time (thetime+timeinterval) obj.pos – position at thetime plus 1 tick
v1=(t2-t1)/timeinterval; --velocity at one tick before frame f (unit: lengthunits/tick)
v2=(t3-t1)/timeinterval; --velocity at one tick after frame f
v= (v1+v2)/2; --the average of both velocities approximates velocity at frame f
append velocity v;
)
Note that this would deliver velocities in lengthunists/tick and with a direction. If you wanted it to be lengthunits/frame you would have to multiply it with ticks_per_frame:
v_frame=v*ticks_per_frame;
If you only want the modulus of the velocity, just relplace
v= (v1+v2)/2;
with
v= length ((v1+v2)/2).
It is always better to work with vectors as long as possible and calculate the modulus at the very last stage because otherwise a lot of information gets lost and the result becomes inaccurate.
I didn’t try anthing of the above myself since i can’t access max right now, so i might be wrong with the syntax or maybe max doesn’t interpolate on a subframe scale… I don’t know.
Btw.:
Velocity is defined at wikipedia (and after what i have learned during my first 2 semesters of physics):
In physics, velocity is defined as the rate of change of position. It is a vector quantity physical, both speed and direction are required to define it.
->So speed is just the modulus of the velocity and velocity itself is a vector.
I think the method of averaging the previous (t-1) and future (t+1) velocity integrations would yield more accurate readings at time t, like you say Boya.
What’s weird about extrapolating measurements from animation curves is that they are all functions of time, they all are some form of cubic bezier interpolation from point to point, and they aren’t necessarily continuous. Basically all of the information is there, and we are starting with position and working backwards instead of starting with acceleration and working towards position.
In the method you outlined you took the velocity vector from t-1 to t, and also the vector from t to t+1, then averaged them. An observation worth noting is that taking the vector from t-1 to t+1 and dividing that by two would yield the same answer. We can prove this algebraically if we set up some variables:
i1 = (position at t) – (position at t-1) (integration1)
i2 = (position at t+1) – (position at t) (integration2)
i3 = (position at t+1) – (position at t-1) (integration3)
So:
i3 = i1 + i2 (because of vector addition rules)
You can see the averaging method is equal to:
i3/2 = (i1 + i2)/2
I think the accuracy of any derived functions such as velocity and acceleration is linearly dependent on the amount of samples you take on the position curve, as long as we stay thinking in the form of discrete time steps and discrete velocity vectors (or integrations) at those time steps. Of course more accuracy could be achieved through brute force, but this isn’t usually useful. If you wanted more accuracy you’d have to have access to the tangent information at each keyframe. So finding velocity between points p1 and p2 depends on the in and out vectors of p1 and p2, which we can call v1 and v2 (again assuming that 3ds Max uses cubic bezier interpolation for keyframes, can someone confirm this?). The velocity function between p1 and p2 is then the general derivative of that function, which is also a cubic polynomial. Perhaps eek can share some insight on finding the derivatives of cubic polynomials, since I believe a lot of his research pertains to this area.
Granted, a lot of these methods probably aren’t necessary for the OP’s problem since a more simple velocity extraction at a single frame is computationally cheaper. I think the questions are still relevant since the conversation could be potentially enriching for its users.
It sucks that max doesn’t have the derivative functionality built in… It sure would be the most accurate method to deal with that.
I’m not sure where i saw it, but i think in combustion you can switch between normal curve view and the derivative of the curve.
I think for animators too it can be very important to compare or set accelerations in their movements, which could be easily achieved if just such a derivative-view was available.
About the averaging: Now i see it too, what i did was quiet cumbersome… But the keypoint was about the tick-accuracy anyway^^