3D motion paths

I have a motion path in 3D space (a series of joined bezier curves). The application I’m working on allows the user to create graphics animations. Suppose I have a bitmap placed on a given motion path. I’m trying to align the front face of the bitmap to the motion path.

the problem basically boils down to this:
I have two vectors - the bitmaps surface normal vector (always <0,0,1>) and the vector defined by the object’s xyz position at time t and t+1 - this vector would be (t+1x-tx,t+1y-ty,t+1z-tz);

now, I need to subject the bitmap to a certain series of rotations in order to align its normal vector to the vector defined by the path.

I had tried mapping the path vector first onto the xy plane, determining the y rotation needed, then mapping the vector onto the yz plane in order to figure out the x rotation. Apparently there’s a z rotation element which I’m not able to figure out.

I hope I’ve made what I’m trying to do a little clear :slight_smile: .

So, I don’t want the object on the path to simply position itself at the XYZ positions but also face the direction it’s going in.

Thanks for any help.

Take crossproduct of normal and path normal, dotproduct for the angle (side must be taken into account as well!), opengl style rotation (with the crossproduct and angle as parameters) to create the rotation matrix. Then you have a mapping rotation.

I actually came up with a different solution but yours seems more elegant.

I’ll give it a shot.

Thank you.

Yeah, there’s an issue if path normal z component is < 0.

What did you mean by side must be considered?

something to do with the dot product < 0?

Well, the crossproduct + the path normal span up a plane, depending on which side of it the object normal points the rotation angle must be positive or negative.

Here’s an aid function i wrote for this:

float vec_virtual_side( float *vec1, float *vec2 )
	vec3_t normal1, normal2;

	vec_crossproduct( normal1, vec1, vec2 );
	vec_crossproduct( normal2, normal1, vec2 );

	return ( vec_cosine( normal2, vec1 ) > 0 ) ? 1.0f : -1.0f;

Of course you can save some operations, since you have to compute the first crossproduct anyways (the rotation axis), so you can reuse it there.

Usage is:

float angle = vec_virtual_side( normal1, normal2 ) * RAD2DEG(acos(vec_cosine( normal1, normal2 )));