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