# Rotation values from Tangent to Curve (Vector)

## Recommended Posts

Sevans    204
Hi, I have a vector, the tangent to a curve infact, and I would like to make something that is riding on the curve rotate to face in the direction of the vector (forward in relation to it traveling down the curve). How do I turn the vector into rotation values that I can pump into a rotation matrix? Thanks much! -sevans

##### Share on other sites
erissian    727
Assuming that the current facing (F) and the tangent (T) vectors are normalized, the angle between them is cos-1(F⋅T)

To get the angle between x,y,and z:
angle_x = acos(dot(T,X));
angle_y = acos(dot(T,Y));
angle_z = acos(dot(T,Z));

Where X=Vector(1,0,0), etc.

But simplifying that:
angle_x = acos(T.x);
angle_y = acos(T.y);
angle_z = acos(T.z);

Again, that's assuming T is normalized.

That's the jist of it anyways.

##### Share on other sites
Sevans    204
Here is the basic c++ style psuedo code of what I am doing.

// calculate the rotations needed to build rotation matricies// somePlaceOnCurve is a point on the curve I am located atcalcRotations(){   Vector3 tanVec = curveFunction.derivitive.evalAt( somePlaceOnCurve );   // normalize the vector   normalize tanVec;   // use acos to find the angles, convert to degrees   double angleX = radiansToDegrees( acos( tanVec.v1 ) );   double angleY = radiansToDegrees( acos( tanVec.v2 ) );   double angleZ = radiansToDegrees( acos( tanVec.v3 ) );   // rotate!   // just do y for now   glRotated( angleY, 0,1,0 );}// T is a Vector3, the tangent vector from my last post// normalize the Tangent vectorVector3 normalize(Vector3 T){   // find length of the vector T   length = vectorLength(T);      T.x = T.x / length;   T.y = T.y / length;   T.z = T.z / length;   return T;}// find the length of the vector Tdouble vectorLength(Vector3 T){   GLdouble result = dot( T, T );   result = sqrt( result );   return result;}// find the dot product of the two vectorsdouble dot( Vector3 p1, Vector3 p2){   return p1.x * p2.x + p1.y * p2.y + p1.z * p2.z;}

Let me explain a little about my curve. For now it is an ellipse with all points on the same y plane. So an average point on the line is (X, 1, Z) for some X and Z.

With the rotation's algorithm shown above, angleY is always 90 degrees. Is there some other way that I should be interpreting these values that are in angleX, angleY, angleZ?

Thanks much!

-Sevans

##### Share on other sites
haegarr    7372
The way for incremental rotation would be a single vector to vector rotation step. It uses the now obsolete facing vector and rotates it to match the current tangent vector. Incremental rotation has the advantage not to suffer from abrupt mirroring when crossing poles (at least as long as the increments are small enough).

Computing the plane of rotation by determining the plane's (unit length) normal
n := t' x v'
where t' is the normalized tangent vector and v' is the normalized original vector, and the angle between these both vectors
arad := cos-1( t' . v' )
one can use the axis/angle pair to rotation matrix conversion, e.g. directly available in OpenGL by
glRotatef( a_deg, n.x, n.y, n.z )
or by computing the matrix self (I can post it if it is unknown).

##### Share on other sites
erissian    727
Rereading you question, you probably want to rotate around an arbitrary axis:

That axis being: F⊗T/|F⊗T|
The angle being cos-1(F⋅T/|F⋅T|)

##### Share on other sites
Sevans    204
Quote:
 Original post by erissianRereading you question, you probably want to rotate around an arbitrary axis:That axis being: F⊗T/|F⊗T|The angle being cos-1(F⋅T/|F⋅T|)

I take it that the dots are dot product
the circles with crosses are the cross product
and the || pipes are absolute value?

if the || pipes are length, where is that coming from?
the dot product returns a scalar.

Lastly, can anyone define the facing vector for me and leave a small example? I thought I knew what it is, but I am starting to think that may have been my problem all along.

Thanks again,

-sevans

[Edited by - Sevans on November 9, 2006 3:50:31 PM]

##### Share on other sites
Sevans    204

Quote:
 Original post by erissianRereading you question, you probably want to rotate around an arbitrary axis:That axis being: F⊗T/|F⊗T|The angle being cos-1(F⋅T/|F⋅T|)

I take it that the dots are dot product
the circles with crosses are the cross product
and the || pipes are absolute value?

if the || pipes are length, where is that coming from?
the dot product returns a scalar.

Also, can anyone define the facing vector for me and leave a small example? I thought I knew what it is, but I am starting to think that may have been my problem all along.

Lastly, I want to note that the method which haegarr posted worked beautifully when my curve has a constant y value, however if the curve moves up in y value, the object travels fine "up hill" (y axis being up) but then as it travels "down hill" it begins to rotate around the curve it is traveling on. and eventually flips all the way around befor hitting the end of the curve where the y levels back out. Anyone have any ideas on why this is? I'm going to keep at it but hints are appreciated!

Thanks again,

-sevans

##### Share on other sites
erissian    727
In a large font, ⊗ will look like an X surrounded by a circle. That's the cross product.
And you're right about the dot too. It's a dot product.

The use I describe comes from the two properties:
|(A/|A|)|=1
and
F⋅T = |F||T|cosΘ
therefore, F⋅T/|F||T| = cosΘ

The first one being important in that if your axis has a length other than 1, then it will scale as well as rotate.

##### Share on other sites
Sevans    204
Sorry about the double post, newbie mistake :(

Okay, well that helps, but what if I do not want rotation (for it to roll around the curve like it is)? is there a way that I can make my object rotate side to side to "turn" around curves and to "tilt" forward and backward on hills and slopes, without "leaning" to either side? How would I go about pulling that rotation out of this (the flip over)?

Something to note, the Z axis of the object lies on the curve it is following

Thanks again,

-sevans

##### Share on other sites
jyk    2094
Quote:
 Original post by SevansOkay, well that helps, but what if I do not want rotation (for it to roll around the curve like it is)? is there a way that I can make my object rotate side to side to "turn" around curves and to "tilt" forward and backward on hills and slopes, without "leaning" to either side?
You might be looking for a 'fixed reference frame'. In this case the reference vector would presumably be the world 'up' vector; the basis vectors of the object's local frame would then be computed as follows:

1. Forward = normalized curve tangent at t

2. Side = normalized cross product of forward and reference vector

3. Up = cross product of forward and side

I may have gotten the permutation wrong there (i.e. negative determinant), but I'm too lazy to go and back and check so I'll leave that to you :) In any case, with this method your object will follow the curve and 'pitch' along with it, but will never roll (what you're calling a 'lean').

The algorithm may fail if the path of the curve ever goes straight up or down, but if you know this will never happen, the fixed reference frame is probably a good choice.

##### Share on other sites
Sevans    204
So once I have the:
1. Forward = normalized curve tangent at t
2. Side = normalized cross product of forward and reference vector
3. Up = cross product of forward and side

How do I build a rotation that I can pass to GL out of it?

-sevans