[comp.sys.sgi] Rotations about an arbitrary axis

jdchrist@watcgl.waterloo.edu (Dan Christensen) (06/01/90)

In article <SPENCER.90May22144823@spline.eecs.umich.edu> spencer@eecs.umich.edu (Spencer W. Thomas) writes:
>In article <9005171647.AA14106@baby.swmed.utexas.edu> rose@BABY.SWMED.UTEXAS.EDU (Rose Oguz) writes:
>[Problem of rotation about an arbitrary axis.]
>> Basically, I have two vectors coming
>> from the same point and one of the vectors needs to be rotated into the 
>> other.
>
>	You want to rotate the vector V1 into the vector V2.  We can
>do this in two steps: (1) rotate V1 to the X axis and then (2) rotate
>the X axis to V2.  (Why do this, you say?  Because each step is easy.)

But there is more than one rotation mapping a vector V1 to a vector V2.
The final result can be oriented in any way about V2.  The original
poster indicated that he wanted the one that rotates about V1xV2,
ie. the most "direct" rotation.  I don't think that your solution 
does this. 

For example, suppose in a right handed coordinate system the poster
wants to rotate the y axis to the z axis (by rotating about y cross z,
ie. the x axis).  This will map y -> z, z -> -y and x -> x.  I believe
that your solution will map y -> z, z -> -x and x -> -y which is
probably not what is wanted.  (I may have the details wrong, but I
think the idea is right.)

Here is some C code that will do what the poster wants.  To produce
the input vector use

axis = V1 x V2   (May have the order backwards.  Can't remember.)
len = length( axis )
axis = axis * arcsin( len ) / len

Since the cross product produces a vector whose length is the
sine of the angle between the two vectors, we must scale the
vector as above.

/* Takes a vector whose direction defines an axis of rotation and whose
 * length is the angle of rotation in radians and fills in the corresponding
 * (4x4) rotation matrix.  Obtained from a paper by Michael Pique */
void      vector_rot(drot, rotation)
double   *drot;
Matrix    rotation;
{
  double    s, c, t, a;
  int       i, j;

  a = sqrt(drot[0] * drot[0] + drot[1] * drot[1] + drot[2] * drot[2]);

  if (a != 0.0)
  {
    drot[0] /= a;
    drot[1] /= a;
    drot[2] /= a;
  }

  s = sin(a);
  c = cos(a);
  t = 1.0 - c;

  rotation[0][0] = t * drot[0] * drot[0] + c;
  rotation[0][1] = t * drot[0] * drot[1] + s * drot[2];
  rotation[0][2] = t * drot[0] * drot[2] - s * drot[1];
  rotation[0][3] = 0;
  rotation[1][0] = t * drot[0] * drot[1] - s * drot[2];
  rotation[1][1] = t * drot[1] * drot[1] + c;
  rotation[1][2] = t * drot[1] * drot[2] + s * drot[0];
  rotation[1][3] = 0;
  rotation[2][0] = t * drot[0] * drot[2] + s * drot[1];
  rotation[2][1] = t * drot[1] * drot[2] - s * drot[0];
  rotation[2][2] = t * drot[2] * drot[2] + c;
  rotation[2][3] = 0;
  rotation[3][0] = 0;
  rotation[3][1] = 0;
  rotation[3][2] = 0;
  rotation[3][3] = 1;
}

Dan Christensen
jdchrist@watcgl.uwaterloo.ca

rose@BABY.SWMED.UTEXAS.EDU (Rose Oguz) (06/01/90)

In article <1990May31.171937.14296@watcgl.waterloo.edu>,
jdchrist@watcgl.uwaterloo.ca (Dan Christensen) writes:

>In article <SPENCER.90May22144823@spline.eecs.umich.edu> spencer@eecs.umich.edu (Spencer W. Thomas) writes:
>>In article <9005171647.AA14106@baby.swmed.utexas.edu> rose@BABY.SWMED.UTEXAS.EDU (Rose Oguz) writes:
>>[Problem of rotation about an arbitrary axis.]
>>> Basically, I have two vectors coming
>>> from the same point and one of the vectors needs to be rotated into the 
>>> other.
>>
>>	You want to rotate the vector V1 into the vector V2.  We can
>>do this in two steps: (1) rotate V1 to the X axis and then (2) rotate
>>the X axis to V2.  (Why do this, you say?  Because each step is easy.)
>
>But there is more than one rotation mapping a vector V1 to a vector V2.
>The final result can be oriented in any way about V2.  The original
>poster indicated that he wanted the one that rotates about V1xV2,
>ie. the most "direct" rotation.  I don't think that your solution 
>does this. 

What I (the poster of the original question) wanted to was exactly map
vector V1 onto V2.  In other words, all points on one vector would be
the exact points on the other vector with the heads of the vectors
matched and the tails of the vectors matched.  

The algorithm suggested by Spencer Thomas works.  I know because I
implemented a modified version because my application wasn't simply
mapping one vector to another.  The method I used also comes from
Foley and Van Dam's Fundamentals of Interactive Computer Graphics.

Basically, there are only 2 rotations that can map one vector into
another, clockwise and counterclockwise, if you will.  I'm not sure
that you want me to go into detail about the above mentioned
algorithm; so, I won't now.  However, I will if anyone indicates so,
but I think article <SPENCER.90May22144823@spline.eecs.umich.edu>, by
spencer@eecs.umich.edu (Spencer W. Thomas) explains the algorithm
quite clearly.

>For example, suppose in a right handed coordinate system the poster
>wants to rotate the y axis to the z axis (by rotating about y cross z,
>ie. the x axis).  This will map y -> z, z -> -y and x -> x.  I believe
>that your solution will map y -> z, z -> -x and x -> -y which is
>probably not what is wanted.  (I may have the details wrong, but I
>think the idea is right.)
>
>Here is some C code that will do what the poster wants.  
> ...
>/* Obtained from a paper by Michael Pique */
I have glanced at the code, but I have not spent much time with it.
I'm not sure of what you've indicated.  However, if you could direct
me to the paper by Michael Pique, I will try to spend some time with
it.

					
					Rose

spencer@eecs.umich.edu (Spencer W. Thomas) (06/01/90)

In article <1990May31.171937.14296@watcgl.waterloo.edu> jdchrist@watcgl.waterloo.edu (Dan Christensen) writes:

me> In article <SPENCER.90May22144823@spline.eecs.umich.edu> spencer@eecs.umich.edu (Spencer W. Thomas) writes:
me>	You want to rotate the vector V1 into the vector V2.  We can
me>do this in two steps: (1) rotate V1 to the X axis and then (2) rotate
me>the X axis to V2.  (Why do this, you say?  Because each step is easy.)

> But there is more than one rotation mapping a vector V1 to a vector V2.
> The final result can be oriented in any way about V2.  The original
> poster indicated that he wanted the one that rotates about V1xV2,
> ie. the most "direct" rotation.  I don't think that your solution 
> does this. 

> For example, suppose in a right handed coordinate system the poster
> wants to rotate the y axis to the z axis (by rotating about y cross z,
> ie. the x axis).  This will map y -> z, z -> -y and x -> x.  I believe
> that your solution will map y -> z, z -> -x and x -> -y which is
> probably not what is wanted.  (I may have the details wrong, but I
> think the idea is right.)

I agree that the problem, as I stated it, is ill-defined.  However, my
solution definitely maps the normal vector onto itself, by
construction.  The first matrix takes v1->x, n->z (and m->y), the
second matrix takes (x->v2, z->n (and y->p)).  Thus, the normal vector
(rotation axis) remains fixed.  Since each matrix is carefully
constructed to be a pure rotation, the result must be a pure rotation.

Let's try it with your example.

1.	n = v1 x v2 = (0 1 0) x (0 0 1) = (1 0 0)
2.	m = n x v1 = (1 0 0) x (0 1 0) = (0 0 1)
3.	R1 = (v1' m' n') = (0 0 1)
			   (1 0 0)
			   (0 1 0)
4.	p = n x v2 = (1 0 0) x (0 0 1) = (0 -1 0)
5.	R2 = (v2) = (0  0 1)
	     ( p)   (0 -1 0)
	     ( n)   (1  0 0)
6.	R1 R2 = (1  0  0)
		(0  0  1)
		(0 -1  0)

So the final result takes x -> x, y -> z, and z -> -y, as desired.

--
=Spencer (spencer@eecs.umich.edu)

jdchrist@watcgl.waterloo.edu (Dan Christensen) (06/02/90)

In article <SPENCER.90Jun1121404@spline.eecs.umich.edu> spencer@eecs.umich.edu (Spencer W. Thomas) writes:
>In article <1990May31.171937.14296@watcgl.waterloo.edu> jdchrist@watcgl.waterloo.edu (Dan Christensen) writes:
>
>> But there is more than one rotation mapping a vector V1 to a vector V2.
>> The final result can be oriented in any way about V2.  The original
>> poster indicated that he wanted the one that rotates about V1xV2,
>> ie. the most "direct" rotation.  I don't think that your solution 
>> does this. 
>
>I agree that the problem, as I stated it, is ill-defined.  However, my
>solution definitely maps the normal vector onto itself, by
>construction.  

Sorry, your solution does work.  My point was that the problem was
ill-defined.  Thanks for working out the details.

Dan Christensen