A spline that can calculate consistent orientation

Started by
7 comments, last by alvaro 12 years, 10 months ago
I have a requirement to create a spline from a simple set of 3D points, and as far as position and tangent this is fine. But I also need to be able to get the full orientation at any point along the spline.
The tangent at any point can be taken as the x-axis so I know the y/z plane but how to establish a system which will be stable? At the start of the spline it is free to pick any valid orientation, the requirement is simply that as you traverse the spline the orientation returns a 'natural' result. What I mean by that is I I rendered a textured tube along the spline based on the coordinates, it would not twist/torque - I don't quite know a better way to put that in words but I hope it's clear.

One option I have (I think) is to repeatedly move a small distance along the spline, and at each point I take the y/z vectors from the previous point and find the smallest rotation which will make them lie in the new plane for the x-axis at the new point. I can do this once per frame, maybe for each control-point on the spline, and can then repeat this for arbitrary points based on the stored values for each control-point.

But I wondered if there is a simple way to make it work without having to traverse the spline. I am suspicious that there isn't but I'd welcome any discussion.

To re-iterate the idea is not to force a given orientation, but simply that given the orientation at the start, this will be transferred along the length of the spline... i.e. if the spline was totally straight the x/y/z axes would be identical at any point.

www.simulatedmedicine.com - medical simulation software

Looking to find experienced Ogre & shader developers/artists. PM me or contact through website with a contact email address if interested.

Advertisement
[font="arial, verdana, tahoma, sans-serif"]if you wanted it to look natural some twisting would probably be necessary, perhaps you could do something like orientate the local y-axis along the curvature vector for the spline? and when the curvature is not defined, keep the previous orientation of when it was (or default if it has not yet been defineable).[/font]
@The OP: I'm not sure if there's a better solution, but the parallel transport frame (which is somewhat similar to what you described in your post) is what I'd usually recommend for this.
If you don't have any straight sections, you can use the Frenet-Serret frame.

EDIT: If you do have straight sections you can patch things, but it's a bit messy to explain.

[font="arial, verdana, tahoma, sans-serif"]if you wanted it to look natural some twisting would probably be necessary[/font]
Yeah I mean it should have a 'natural' twisting. Imagine a garden hose or something.

www.simulatedmedicine.com - medical simulation software

Looking to find experienced Ogre & shader developers/artists. PM me or contact through website with a contact email address if interested.


If you don't have any straight sections, you can use the Frenet-Serret frame.

EDIT: If you do have straight sections you can patch things, but it's a bit messy to explain.

This sounds ideal, the basic ideal makes sense:
[font="sans-serif"]The tangent, normal, and binormal unit vectors, often called [/font]T[font="sans-serif"], [/font]N[font="sans-serif"], and [/font]B[font="sans-serif"], or collectively the [/font]Frenet–Serret frame[font="sans-serif"] or [/font]TNB frame [font="sans-serif"]are defined as follows:[/font]
  • T is the unit vector tangent to the curve, pointing in the direction of motion.
  • N is the derivative of T with respect to the arclength parameter of the curve, divided by its length.
  • B is the cross product of T and N.[/quote]
[font="sans-serif"]But then they only talk about it in terms of calculus and I wonder how to differentiate wrt arclength...[/font]
[font="sans-serif"] [/font]
[font="sans-serif"] [/font]
[font="sans-serif"][font=arial, verdana, tahoma, sans-serif][size=2]

@The OP: I'm not sure if there's a better solution, but the parallel transport frame (which is somewhat similar to what you described in your post) is what I'd usually recommend for this.

Looking at this on wikipedia (http://en.wikipedia.org/wiki/Parallel_transport) it also sounds good but they describe it in such an abstract mathematical way I'm lost. Manifolds and bundles, etc.[/font][font=arial, verdana, tahoma, sans-serif][size=2]
[/font][font=arial, verdana, tahoma, sans-serif][size=2]Anyone got any links to more applied versions, where we have a spline rather than a mathematically defined curve?[/font][/font]


www.simulatedmedicine.com - medical simulation software

Looking to find experienced Ogre & shader developers/artists. PM me or contact through website with a contact email address if interested.


[quote name='alvaro' timestamp='1306452340' post='4816231']
If you don't have any straight sections, you can use the Frenet-Serret frame.

EDIT: If you do have straight sections you can patch things, but it's a bit messy to explain.

This sounds ideal, the basic ideal makes sense:
[font="sans-serif"]The tangent, normal, and binormal unit vectors, often called [/font]T[font="sans-serif"], [/font]N[font="sans-serif"], and [/font]B[font="sans-serif"], or collectively the [/font]Frenet–Serret frame[font="sans-serif"] or [/font]TNB frame [font="sans-serif"]are defined as follows:[/font]
  • T is the unit vector tangent to the curve, pointing in the direction of motion.
  • N is the derivative of T with respect to the arclength parameter of the curve, divided by its length.
  • B is the cross product of T and N.[/quote]
[font="sans-serif"]But then they only talk about it in terms of calculus and I wonder how to differentiate wrt arclength...[/font]
[/quote]

You don't need to differentiate with respect to arc-length: Just differentiate with respect to time and then normalize the result.

You actually have parametric polynomial formulas for your splines, so everything can be computed with a bit of work. Alternatively, you could compute approximations the following way:

Vector3D spline(double time);

Vector3D T(double time) {
Vector3D v = spline(time + 1e-6) - spline(time - 1e-6);
return v / length(v);
}


Vector3D N(double time) {
Vector3D v = T(time + 1e-6) - T(time - 1e-6);
return v / length(v);
}

Vector3D B(double time) {
return cross_product(T(time), N(time));
}


NOTE: Code optimized for readability: Some redundant evaluations could be saved.
So, what happens when a spline is straight then?

edit: thanks by the way

www.simulatedmedicine.com - medical simulation software

Looking to find experienced Ogre & shader developers/artists. PM me or contact through website with a contact email address if interested.


So, what happens when a spline is straight then?


Well, the computation of N would give you a division by zero. You could in this case remember what N was in the previous step and just continue using that value (since T isn't changing this is still a perfectly good orthogonal vector). The problem is that when you get to the next non-straight piece, N will start having ideas of its own about what it should be, and you would get a discontinuity.

I think what I would do to ensure continuity is find the beginning and the end of the straight piece, compute N at the extremes and interpolate between them using slerp.

This topic is closed to new replies.

Advertisement