Jump to content
  • Advertisement
Sign in to follow this  
JDX_John

A spline that can calculate consistent orientation

This topic is 2585 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
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]

Share this post


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

[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.

Share this post


Link to post
Share on other sites

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]


Share this post


Link to post
Share on other sites

[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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!