Sign in to follow this  
JDX_John

A spline that can calculate consistent orientation

Recommended Posts

JDX_John    292
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.

Share this post


Link to post
Share on other sites
[font="arial, verdana, tahoma, sans-serif"][size="2"]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).[/size][/font]

Share this post


Link to post
Share on other sites
jyk    2094
@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.

Share this post


Link to post
Share on other sites
alvaro    21246
If you don't have any straight sections, you can use [url="http://en.wikipedia.org/wiki/Frenet-Serret_formulas"]the Frenet-Serret frame[/url].

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

Share this post


Link to post
Share on other sites
JDX_John    292
[quote name='luca-deltodesco' timestamp='1306444980' post='4816185']
[font="arial, verdana, tahoma, sans-serif"][size="2"]if you wanted it to look natural some twisting would probably be necessary[/size][/font][/quote]Yeah I mean it should have a 'natural' twisting. Imagine a garden hose or something.

Share this post


Link to post
Share on other sites
JDX_John    292
[quote name='alvaro' timestamp='1306452340' post='4816231']
If you don't have any straight sections, you can use [url="http://en.wikipedia.org/wiki/Frenet-Serret_formulas"]the Frenet-Serret frame[/url].

EDIT: If you do have straight sections you can patch things, but it's a bit messy to explain.
[/quote]
This sounds ideal, the basic ideal makes sense:[quote][font="sans-serif"][size="2"]The tangent, normal, and binormal unit vectors, often called [/size][/font][b]T[/b][font="sans-serif"][size="2"], [/size][/font][b]N[/b][font="sans-serif"][size="2"], and [/size][/font][b]B[/b][font="sans-serif"][size="2"], or collectively the [/size][/font][b]Frenet–Serret frame[/b][font="sans-serif"][size="2"] or [/size][/font][b]TNB frame [/b][font="sans-serif"][size="2"]are defined as follows:[/size][/font][list][*][b]T[/b] is the unit vector [url="http://en.wikipedia.org/wiki/Tangent_vector"]tangent[/url] to the curve, pointing in the direction of motion.[*][b]N[/b] is the derivative of [b]T[/b] with respect to the [url="http://en.wikipedia.org/wiki/Curve#Lengths_of_curves"]arclength parameter[/url] of the curve, divided by its length.[*][b]B[/b] is the [url="http://en.wikipedia.org/wiki/Cross_product"]cross product[/url] of [i]T[/i] and [i]N[/i].[/quote][/list][font="sans-serif"][size="2"]But then they only talk about it in terms of calculus and I wonder how to differentiate wrt arclength...[/size][/font]
[font="sans-serif"] [/font]
[font="sans-serif"] [/font]
[font="sans-serif"][size="2"][font=arial, verdana, tahoma, sans-serif][size=2][quote name='jyk' timestamp='1306450585' post='4816213']
@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.
[/quote]
Looking at this on wikipedia ([url="http://en.wikipedia.org/wiki/Parallel_transport"]http://en.wikipedia.org/wiki/Parallel_transport[/url]) it also sounds good but they describe it in such an abstract mathematical way I'm lost. Manifolds and bundles, etc.[/size][/font][font=arial, verdana, tahoma, sans-serif][size=2]
[/size][/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?[/size][/font][/size][/font]


Share this post


Link to post
Share on other sites
alvaro    21246
[quote name='JDX_John' timestamp='1306480067' post='4816328']
[quote name='alvaro' timestamp='1306452340' post='4816231']
If you don't have any straight sections, you can use [url="http://en.wikipedia.org/wiki/Frenet-Serret_formulas"]the Frenet-Serret frame[/url].

EDIT: If you do have straight sections you can patch things, but it's a bit messy to explain.
[/quote]
This sounds ideal, the basic ideal makes sense:[quote][font="sans-serif"][size="2"]The tangent, normal, and binormal unit vectors, often called [/size][/font][b]T[/b][font="sans-serif"][size="2"], [/size][/font][b]N[/b][font="sans-serif"][size="2"], and [/size][/font][b]B[/b][font="sans-serif"][size="2"], or collectively the [/size][/font][b]Frenet–Serret frame[/b][font="sans-serif"][size="2"] or [/size][/font][b]TNB frame [/b][font="sans-serif"][size="2"]are defined as follows:[/size][/font][list][*][b]T[/b] is the unit vector [url="http://en.wikipedia.org/wiki/Tangent_vector"]tangent[/url] to the curve, pointing in the direction of motion.[*][b]N[/b] is the derivative of [b]T[/b] with respect to the [url="http://en.wikipedia.org/wiki/Curve#Lengths_of_curves"]arclength parameter[/url] of the curve, divided by its length.[*][b]B[/b] is the [url="http://en.wikipedia.org/wiki/Cross_product"]cross product[/url] of [i]T[/i] and [i]N[/i].[/quote][/list][font="sans-serif"][size="2"]But then they only talk about it in terms of calculus and I wonder how to differentiate wrt arclength...[/size][/font]
[/quote]

You don't need to differentiate with respect to arc-length: [url="http://en.wikipedia.org/wiki/Frenet-Serret_formulas#Other_expressions_of_the_frame"]Just differentiate with respect to time and then normalize the result[/url].

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:

[code]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));
}
[/code]

NOTE: Code optimized for readability: Some redundant evaluations could be saved.

Share this post


Link to post
Share on other sites
alvaro    21246
[quote name='JDX_John' timestamp='1306504465' post='4816426']
So, what happens when a spline [i]is[/i] straight then?
[/quote]

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this