home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / geometry / transform3 / tm3rotate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-13  |  4.9 KB  |  196 lines

  1. /* Copyright (c) 1992 The Geometry Center; University of Minnesota
  2.    1300 South Second Street;  Minneapolis, MN  55454, USA;
  3.    
  4. This file is part of geomview/OOGL. geomview/OOGL is free software;
  5. you can redistribute it and/or modify it only under the terms given in
  6. the file COPYING, which you should have received along with this file.
  7. This and other related software may be obtained via anonymous ftp from
  8. geom.umn.edu; email: software@geom.umn.edu. */
  9.  
  10. /* Authors: Charlie Gunn, Pat Hanrahan, Stuart Levy, Tamara Munzner,
  11.    Mark Phillips, Nathaniel Thurston */
  12.  
  13. #include <math.h>
  14. #include "radians.h"
  15. #include "transform3.h"
  16.  
  17. HPoint3 TM3_XAXIS = { 1.0, 0.0, 0.0, 0.0 };
  18. HPoint3 TM3_YAXIS = { 0.0, 1.0, 0.0, 0.0 };
  19. HPoint3 TM3_ZAXIS = { 0.0, 0.0, 1.0, 0.0 };
  20.  
  21. void
  22. Tm3RotateX( T, angle )
  23.     Transform3 T;
  24.     float angle;
  25. {
  26.     Tm3Identity( T );
  27.     Ctm3RotateX( T, angle );
  28. }
  29.  
  30. void
  31. Tm3RotateY( T, angle )
  32.     Transform3 T;
  33.     float angle;
  34. {
  35.     Tm3Identity( T );
  36.     Ctm3RotateY( T, angle );
  37. }
  38.  
  39. void
  40. Tm3RotateZ( T, angle )
  41.     Transform3 T;
  42.     float angle;
  43. {
  44.     Tm3Identity( T );
  45.     Ctm3RotateZ( T, angle );
  46. }
  47.  
  48. /*
  49.  * Construct the matrix for a rotation about an axis.
  50.  */
  51. void
  52. Tm3Rotate( T, angle, axis)
  53.     Transform3 T;
  54.     float angle;
  55.     HPoint3 *axis;
  56. {
  57.     HPoint3 Vu;
  58.     float sinA, cosA, versA;
  59.     
  60.     if(      axis == &TM3_XAXIS ) Tm3RotateX( T, angle );
  61.     else if( axis == &TM3_YAXIS ) Tm3RotateY( T, angle );
  62.     else if( axis == &TM3_ZAXIS ) Tm3RotateZ( T, angle );
  63.     else {
  64.     Pt3Copy( (Point3 *)axis, (Point3 *)&Vu );
  65.     Pt3Unit( (Point3 *)&Vu );
  66.  
  67.     sinA = sin(angle); 
  68.     cosA = cos(angle); 
  69.     versA = 1 - cosA;
  70.  
  71.     Tm3Identity( T );
  72.     T[X][X] = Vu.x*Vu.x*versA + cosA;
  73.     T[Y][X] = Vu.x*Vu.y*versA - Vu.z*sinA;
  74.     T[Z][X] = Vu.x*Vu.z*versA + Vu.y*sinA;
  75.  
  76.     T[X][Y] = Vu.y*Vu.x*versA + Vu.z*sinA;
  77.     T[Y][Y] = Vu.y*Vu.y*versA + cosA;
  78.     T[Z][Y] = Vu.y*Vu.z*versA - Vu.x*sinA;
  79.  
  80.     T[X][Z] = Vu.x*Vu.z*versA - Vu.y*sinA;
  81.     T[Y][Z] = Vu.y*Vu.z*versA + Vu.x*sinA;
  82.     T[Z][Z] = Vu.z*Vu.z*versA + cosA;
  83.     }
  84. }
  85.  
  86. /*
  87.  * Construct the matrix for the geodesic rotation between two vectors.
  88.  */
  89. void
  90. Tm3RotateBetween( T, vfrom, vto )
  91.     Transform3 T;
  92.     Point3 *vfrom, *vto;
  93. {
  94.     Point3 Vu;
  95.     float len, sinA, cosA, versA;
  96.  
  97.     Tm3Identity( T );
  98.     
  99.     len = sqrt(Pt3Dot(vfrom,vfrom) * Pt3Dot(vto,vto));
  100.     if(len == 0) return;
  101.  
  102.     cosA = Pt3Dot(vfrom,vto) / len;
  103.     versA = 1 - cosA;
  104.  
  105.     Pt3Cross( vfrom, vto, &Vu );
  106.     sinA = Pt3Length( &Vu ) / len;
  107.     if(sinA == 0) return;
  108.  
  109.     Pt3Mul( 1/(len*sinA), &Vu, &Vu );    /* Normalize Vu */
  110.  
  111.     T[X][X] = Vu.x*Vu.x*versA + cosA;
  112.     T[Y][X] = Vu.x*Vu.y*versA - Vu.z*sinA;
  113.     T[Z][X] = Vu.x*Vu.z*versA + Vu.y*sinA;
  114.  
  115.     T[X][Y] = Vu.y*Vu.x*versA + Vu.z*sinA;
  116.     T[Y][Y] = Vu.y*Vu.y*versA + cosA;
  117.     T[Z][Y] = Vu.y*Vu.z*versA - Vu.x*sinA;
  118.  
  119.     T[X][Z] = Vu.x*Vu.z*versA - Vu.y*sinA;
  120.     T[Y][Z] = Vu.y*Vu.z*versA + Vu.x*sinA;
  121.     T[Z][Z] = Vu.z*Vu.z*versA + cosA;
  122. }
  123.  
  124. /*-----------------------------------------------------------------------
  125.  * Function:    Tm3RotateTowardZ
  126.  * Description:    Rotation of 3-space moving pt to positive z-axis
  127.  * Args:    T: output matrix
  128.  *        pt: input point
  129.  * Returns:    nonthing
  130.  * Author:    njt (comments by mbp)
  131.  * Date:    (before) Tue Aug 18 23:31:58 1992
  132.  */
  133. void Tm3RotateTowardZ(T, pt)
  134. Transform3 T;
  135. HPoint3 *pt;
  136. {
  137.   Transform3 S;
  138.   float r = pt->z;
  139.   /* Construct T = rotation about x-axis moving pt into x-z plane */
  140.   Tm3Identity(T);
  141.   r = sqrt(pt->y*pt->y + r*r);
  142.   if (r > 0) {
  143.     T[2][1] = -(T[1][2] = pt->y/r);
  144.     T[2][2] = T[1][1] = pt->z/r;
  145.   }
  146.   /* Construct S = rotation about y axis moving T(pt) into y-z plane */
  147.   Tm3Identity(S);
  148.   r = sqrt(pt->x*pt->x + r*r);
  149.   if (r > 0) {
  150.     S[2][0] = -(S[0][2] = pt->x/r);
  151.     S[2][2] = S[0][0] = sqrt(pt->z*pt->z + pt->y*pt->y)/r;
  152.   }
  153.   /* Desired transform is then S * T */
  154.   Tm3Concat(T, S, T);
  155. }
  156.  
  157. /* Tm3CarefulRotateTowardZ gives a matrix which rotates the world
  158.  * about an axis perpinducular to both pos and the z axis, which moves
  159.  * pos to the z axis.  Unlike Tm3RotateTowardZ, the "twist" is well-defined
  160.  * provided that it is not asked to rotate the negative z axis toward
  161.  * the positive z axis.
  162.  */
  163. void Tm3CarefulRotateTowardZ(T, pos)
  164. Transform3 T;
  165. HPoint3 *pos;
  166. {
  167.   Transform3 S;
  168.   Transform3 Sinv;
  169.   HPoint3 perp, axis;
  170.   double dist, c, s;
  171.   /* first, find a rotation takes both pos and the z axis into the xy plane */
  172.   perp.x = -pos->y; perp.y = pos->x; perp.z = 0; perp.w = 1;
  173.   Tm3RotateTowardZ(S, &perp);
  174.    
  175.   /* now, rotate pos and the z axis to this plane */
  176.   axis.x = 0; axis.y = 0; axis.z = -1; axis.w = 1;
  177.   HPt3Transform(S, &axis, &axis);
  178.   HPt3Transform(S, pos, pos);
  179.  
  180.   /* find the rotation matrix for the transformed points */
  181.   c = axis.x * pos->x + axis.y * pos->y;
  182.   s = axis.x * pos->y - axis.y * pos->x;
  183.   dist = sqrt(c*c+s*s);
  184.   Tm3Identity(T);
  185.   if (dist == 0) return;
  186.   c /= dist;
  187.   s /= dist;
  188.   T[0][0] =  c; T[0][1] = s;
  189.   T[1][0] = -s; T[1][1] = c;
  190.  
  191.   /* Finally, conjugate the result back to the original coordinate system */
  192.   Tm3Invert(S, Sinv);
  193.   Tm3Concat(S, T, T);
  194.   Tm3Concat(T, Sinv, T);
  195. }
  196.