TransLn.cpp
上传用户:lhwx1029
上传日期:2013-03-07
资源大小:1173k
文件大小:10k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /** 3DGPL *************************************************
  2.  * ()                                                     *
  3.  * 3-D linear algebra stuff.                              *
  4.  *                                                        *
  5.  * Defines:                                               *
  6.  *  T_vector                 Construct from two points;   *
  7.  *  T_norm                   Norm (length) of a vector;   *
  8.  *                                                        *
  9.  *  T_normal_vectors         From two vectors;            *
  10.  *  T_normal_plane           From three points;           *
  11.  *  T_unit_vector            Normalising a vector;        *
  12.  *  T_scalar_product         Computing the product;       *
  13.  *  T_normal_z_negative      Z component of the normal;   *
  14.  *                                                        *
  15.  *  T_plane                  Coefs for plane equation;    *
  16.  *  T_vertex_on_plane        Vertex belongs to a plane?.  *
  17.  *                                                        *
  18.  * Internal:                                              *
  19.  *  TI_sqrt                  Integer square root.         *
  20.  *                                                        *
  21.  * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca)      *
  22. **********************************************************/
  23. #include "Trans.h"                 /* 3D mathematics */
  24. #include "RayTracing.h"           /* HW_error */
  25. #include <math.h>                           /* float sqrt */
  26. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  27.  * INTERNAL: Computes square root for a long integer     *
  28.  * --------- using iterative bit setting.                *
  29.  *                                                       *
  30.  * RETURNS: The square root.                             *
  31.  * --------                                              *
  32. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  33. #if defined(_FIXED_)
  34. unsigned long TI_sqrt(register unsigned long arg)   
  35. {                                           /* using iterative method */
  36.  register int i;
  37.  register unsigned long nprd,msk=0x8000L,val=0,prd=0;
  38.  for(i=15;i>=0;i--)
  39.  {                                          /* iteratively computing the */
  40.   nprd=prd+(val<<(i+1))+(msk<<i);           /* square */
  41.   if(nprd<=arg) { val|=msk; prd=nprd; }     /* this bit must be in the result */
  42.   msk>>=1;                                  /* next, a lower bit */
  43.  }
  44.  return(val);
  45. }
  46. #endif
  47. /**********************************************************
  48.  * Build a vector from two points.                        *
  49.  *                                                        *
  50.  * RETURNS: Always a pointer to the destanation.          *
  51.  * --------                                               *
  52. **********************************************************/
  53. int *T_vector(int *from1,int *from2,int *to,int dimension)
  54. {
  55.  to[0]=(*from2++)-(*from1++);
  56.  to[1]=(*from2++)-(*from1++);
  57.  if(dimension==3) to[2]=(*from2)-(*from1);
  58.  return(to);
  59. }
  60. /**********************************************************
  61.  * Compute norm (length) of the vector.                   *
  62.  *                                                        *
  63.  * RETURNS: Length of the vector.                         *
  64.  * --------                                               *
  65. **********************************************************/
  66. long T_norm(int *vector)
  67. {
  68. #if defined(_FLOAT_)
  69.  return(sqrt(((float)vector[0])*vector[0]+
  70.              ((float)vector[1])*vector[1]+
  71.              ((float)vector[2])*vector[2]
  72.             )
  73.        );
  74. #endif
  75. #if defined(_FIXED_)
  76.  if((vector[0]>0xffff)||(vector[1]>0xffff)||(vector[2]>0xffff)||
  77.     (vector[0]<-0xffff)||(vector[1]<-0xffff)||(vector[2]<-0xffff)
  78.    )
  79.  {
  80.   return(TI_sqrt(((long)vector[0]>>8)*vector[0]+
  81.                  ((long)vector[1]>>8)*vector[1]+
  82.                  ((long)vector[2]>>8)*vector[2]
  83.                 )<<4                        /* to avoid an overflow: */
  84.         );                                  /* sqrt(a/2**8)==sqrt(a)/2**4 */
  85.  }
  86.  else
  87.  {
  88.   return(TI_sqrt(((long)vector[0])*vector[0]+
  89.                  ((long)vector[1])*vector[1]+
  90.                  ((long)vector[2])*vector[2]
  91.                 )
  92.         );
  93.  }
  94. #endif
  95. }
  96. /**********************************************************
  97.  * Computing a normal through a vector product of two     *
  98.  * vectors.                                               *
  99.  *        _  _  _                                         *
  100.  *      |i  j  k |   _              _                     *
  101.  * N=det|Vx Vy Vz| = i*det|Vy Vz| - j*det|Vx Vz| +        *
  102.  *      |Wx Wy Wz|        |Wy Wz|        |Wx Wz|          *
  103.  *   _                                                    *
  104.  * + k*det|Vx Vy|                                         *
  105.  *        |Wx Wy|                                         *
  106.  *                                                        *
  107. **********************************************************/
  108. void T_normal_vectors(int *v,int *w,int *to)
  109. {
  110.  int n[3];
  111.  long lng;
  112.  n[0]=v[1]*w[2]-v[2]*w[1];
  113.  n[1]=v[2]*w[0]-v[0]*w[2];
  114.  n[2]=v[0]*w[1]-v[1]*w[0];                  /* a vector product */
  115.  lng=T_norm(n);                             /* vector's length */
  116.  if(lng==0) HW_error("(Trans) Found a zero length vector.");
  117.  *to++=(int)((((long)n[0])<<T_LOG_NORMAL_SIZE)/lng);
  118.  *to++=(int)((((long)n[1])<<T_LOG_NORMAL_SIZE)/lng);
  119.  *to  =(int)((((long)n[2])<<T_LOG_NORMAL_SIZE)/lng);
  120. }
  121. /**********************************************************
  122.  * Computing a normal through a vector product of the     *
  123.  * vectors built on three points passed.                  *
  124.  *       _  _  _                                          *
  125.  *      |i  j  k |   _              _                     *
  126.  * N=det|Vx Vy Vz| = i*det|Vy Vz| - j*det|Vx Vz| +        *
  127.  *      |Wx Wy Wz|        |Wy Wz|        |Wx Wz|          *
  128.  *   _                                                    *
  129.  * + k*det|Vx Vy|                                         *
  130.  *        |Wx Wy|                                         *
  131.  *                                                        *
  132. **********************************************************/
  133. void T_normal_plane(int *from1,int *from2,int *from3,
  134.                     int *to
  135.                    )
  136. {
  137.  int v[3],w[3],n[3];
  138.  long lng;
  139.  T_vector(from1,from2,v,3);
  140.  T_vector(from1,from3,w,3);
  141.  n[0]=v[1]*w[2]-v[2]*w[1];
  142.  n[1]=v[2]*w[0]-v[0]*w[2];
  143.  n[2]=v[0]*w[1]-v[1]*w[0];                  /* a vector product */
  144.  lng=T_norm(n);                             /* vector's length */
  145.  if(lng==0) HW_error("(Trans) Found a zero length vector.");
  146.  *to++=(int)((((long)n[0])<<T_LOG_NORMAL_SIZE)/lng);
  147.  *to++=(int)((((long)n[1])<<T_LOG_NORMAL_SIZE)/lng);
  148.  *to  =(int)((((long)n[2])<<T_LOG_NORMAL_SIZE)/lng);
  149. }
  150. /**********************************************************
  151.  * Computing a unit length vector based on two points.    *
  152. **********************************************************/
  153. void T_unit_vector(int *from1,int *from2,int *to)
  154. {
  155.  int v[3];
  156.  long lng;
  157.  T_vector(from1,from2,v,3);                 /* vector V */
  158.  lng=T_norm(v);                             /* length */
  159.  if(lng==0) HW_error("(Trans) Found a zero length vector.");
  160.  *to++=(int)((((long)v[0])<<T_LOG_NORMAL_SIZE)/lng);
  161.  *to++=(int)((((long)v[1])<<T_LOG_NORMAL_SIZE)/lng);
  162.  *to  =(int)((((long)v[2])<<T_LOG_NORMAL_SIZE)/lng);
  163. }
  164. /**********************************************************
  165.  * Computing the scalar product of two unit vectors.      *
  166.  * which were assumed to be built with T_LOG_NORMAL_SIZE  *
  167.  * precision.                                             *
  168.  *                                                        *
  169.  * RETURNS: The scalar product.                           *
  170.  * --------                                               *
  171. **********************************************************/
  172. int T_scalar_product(int *vector1,int *vector2)
  173. {
  174.  return(((long)vector1[0]*(long)vector2[0]+
  175.          (long)vector1[1]*(long)vector2[1]+
  176.          (long)vector1[2]*(long)vector2[2]
  177.         )>>T_LOG_NORMAL_SIZE
  178.        );
  179. }
  180. /**********************************************************
  181.  * Z component of the normal.                             *
  182.  *                                                        *
  183.  * RETURNS: 1 if z component negative, 0 otherwise.       *
  184.  * --------                                               *
  185. **********************************************************/
  186. int T_normal_z_negative(int *from1,int *from2,int *from3)
  187. {
  188.  return((((long)(from2[0]-from1[0]))*(from3[1]-from1[1])-
  189.          ((long)(from2[1]-from1[1]))*(from3[0]-from1[0]))<0
  190.        );                                   /* component of vector product */
  191. }
  192. /**********************************************************
  193.  * Computing coeficients for a plane equation.            *
  194.  *                                                        *
  195.  *        ^ N---------+   (N)(x-x0)==0                    *
  196.  *        |    *x   /   Nx(x-x0)+Ny(y-y0)+Nz(z-z0)==0     *
  197.  *      / |  /    /                                       *
  198.  *    /   |/x0  /   x*Nx+y*Ny+z*Nz-(Nx*x0+Ny*y0+Nz*z0)==0 *
  199.  *  +----------+                                          *
  200.  *                                                        *
  201. **********************************************************/
  202. void T_plane(int *from1,int *from2,int *from3,int *to)
  203. {
  204.  int n[3];
  205.  T_normal_plane(from1,from2,from3,n);       /* normal based on three points */
  206.  *to++=n[0]; *to++=n[1]; *to++=n[2];        /* plane coeficients */
  207.  *to=-(from1[0]*n[0]+from1[1]*n[1]+from1[2]*n[2]);
  208. }
  209. /**********************************************************
  210.  * Putting vertex into a plane equation Ax+By+Cz+D        *
  211.  *                                                        *
  212.  * RETURNS: 0   if a point belongs to a plane;            *
  213.  * -------- "+" if a point is on the normal pointed side; *
  214.  *          "-" if on the other side.                     *
  215. **********************************************************/
  216. int T_vertex_on_plane(int *vertex,int *plane)
  217. {
  218.  return(vertex[0]*plane[0]+
  219.         vertex[1]*plane[1]+
  220.         vertex[2]*plane[2]+
  221.         plane[3]
  222.        );
  223. }
  224. /**********************************************************/