Advertisement

Spline motion ( time parameter irregularity)

Started by February 18, 2003 02:30 AM
9 comments, last by minorlogic 22 years ago
Have a nice way to simulate motion by splines (3d parametric, cubic )( B , Catmull Rom, end e.t i tryed many ), but i need motion with some constant (or near) speed , splines is not regular to time parameter , how can i avoid it ? I think it is solved ? where can i find it?
You can do it basically as you would draw it. You draw a series of straight lines that looks like a spline. The length of those lines is an approximation of the arc length. You can either use a fixed increment or adjust the increment based upon the curvature which reduces the number of points needed for a given margin of error. You could also use subdivision, but I don''t think dividing a segment into two or three subsegments is reliable. The intermediate points could just happen to be where the curve crosses a straight line connecting the end points
Keys to success: Ability, ambition and opportunity.
Advertisement
Thanks , but it is not acceptable for me.
I search exac , not iterative ( by little increment) solution.
Is this what you''re looking for?
Smooth interpolation of irregularly spaced keyframes
"-1 x -1 = +1 is stupid and evil."-- Gene Ray
Here''s a rundown on constant-time beziers w/code samples:

http://zenzer.net/2dnow/viewtopic.php?t=159

2DNow - Yesteryears technology at your fingertips!
To:LNK2001
I sow this , but i can''t understand what they write ....

To:llyod
Thanks, thats the same iterative if understand.
//-----------

To all , i am wandering that to find Length of curve once use the segment distance calculation , LESS complex is to find the 1st derivative on the point set on curve.

Advertisement
quote:
Original post by minorlogic
To:LNK2001
I sow this , but i can't understand what they write ....


Here's a snippet from my spline implementation based on that article. Hope it helps.

K is a member variable in the CSpline class, a std::vector of CSplineFrame.


    struct CSplineFrame{  float x, y; // x and y position of the keyframe  float k; // Gradient at keyframe};// Calculates gradients for all keyframes.void CSpline::CalcGrads(){  for(UINT i=0; i<K.size(); i++)  {    if(0==i) // Gradient for the first keyframe      K[i].k = (K[i+1].y - K[i].y) / (K[i+1].x - K[i].x);    else if(K.size()-1 == i) // Gradient for the last keyframe      K[i].k = (K[i].y - K[i-1].y) / (K[i].x - K[i-1].x);    else // Gradient for all other keyframes.      K[i].k = .5f * (K[i].y - K[i-1].y) / (K[i].x - K[i-1].x) +               .5f * (K[i+1].y - K[i].y) / (K[i+1].x - K[i].x);  }}// Evaluates a single spline value between two keyframes, p1 and p2. // The value of t should be between 0 and 1.// Note that the result is not adjusted for irregularly spaced keyframes.// Also note that CalcGrads() needs to be called first.float CSpline::Eval(UINT p1, UINT p2, float t){  float y1 = K[p1].y;  float y2 = K[p2].y;  float k1 = K[p1].k * (K[p2].x - K[p1].x); // "Adjusted" gradient at p1  float k2 = K[p2].k * (K[p2].x - K[p1].x); // "Adjusted" gradient at p2  float tt = t*t;  float ttt= tt*t;    return y1*(2.0f*ttt - 3.0f*tt + 1.0f) + y2*(3.0f*tt-2.0f*ttt) +          k1*(ttt - 2.0f*tt + t) +           k2*(ttt - tt);}// Evaluates a series of spline values and fills the "values" vector.// dx is the increment between values along the x axis. The values are // evenly spaced, where the first and last values coincides // with the first and last keyframes.// CalcGrads() needs to be called before Eval().void CSpline::Eval(CFrameVector& values, float dx){  UINT ik=0; // Current keyframe index  UINT iv=0; // Current value index  float x = K[ik].x, y, t;  UINT nNumValues = (UINT)((K[K.size()-1].x - K[0].x)/dx);  if(values.size() != nNumValues)    values.resize(nNumValues+1);  while(x<K[K.size()-1].x && iv<nNumValues)  {    t = (x-K[ik].x)/(K[ik+1].x - K[ik].x); // Adjust spacing    y = Eval(ik, ik+1, t); // Get value at x    values[iv].x = x;    values[iv].y = y;    values[iv].k = 0;        iv+=1;    x+= dx;    if(x>=K[ik+1].x)      ik++;  }  values[nNumValues] = K[K.size()-1];  values[nNumValues].k = 0;}    

Edit: Formating...

[edited by - LNK2001 on February 19, 2003 4:44:39 AM]
"-1 x -1 = +1 is stupid and evil."-- Gene Ray
to : LNK2001

struct CSplineFrame{
float x, y; // x and y position of the keyframe
float k; // Gradient at keyframe
};
//----
Ok ! What is a "float x, y; // x and y position of the keyframe"
is it 2d spline or it is begin end end time of spline(seconds) ?

what is a "float k; // Gradient at keyframe" where from "Gradient" in a spline ?

I need that velocity at spline end and begin was exacly defined , how can i do that ?





quote:
Original post by minorlogic
Ok ! What is a "float x, y; // x and y position of the keyframe"
is it 2d spline or it is begin end end time of spline(seconds) ?


Yes, it''s a 2D spline. The keyframe vector has to be sorted by x, and should have 2 or more items (2 gives a straight line). Eval() interpolates between the keyframes.
quote:

what is a "float k; // Gradient at keyframe" where from "Gradient" in a spline ?


Not sure I understand the question, but a gradient is the "direction" of the curve at a certain point.
"-1 x -1 = +1 is stupid and evil."-- Gene Ray
Another link that may be helpful:

www.magic-software.com/Documentation/MovingAtConstantSpeed.pdf

Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net

This topic is closed to new replies.

Advertisement