www.pudn.com > LightTrack.rar > TransLn.cpp


/** 3DGPL *************************************************\ 
 * ()                                                     * 
 * 3-D linear algebra stuff.                              * 
 *                                                        * 
 * Defines:                                               * 
 *  T_vector                 Construct from two points;   * 
 *  T_norm                   Norm (length) of a vector;   * 
 *                                                        * 
 *  T_normal_vectors         From two vectors;            * 
 *  T_normal_plane           From three points;           * 
 *  T_unit_vector            Normalising a vector;        * 
 *  T_scalar_product         Computing the product;       * 
 *  T_normal_z_negative      Z component of the normal;   * 
 *                                                        * 
 *  T_plane                  Coefs for plane equation;    * 
 *  T_vertex_on_plane        Vertex belongs to a plane?.  * 
 *                                                        * 
 * Internal:                                              * 
 *  TI_sqrt                  Integer square root.         * 
 *                                                        * 
 * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca)      * 
\**********************************************************/ 
//TransLn.cpp 
 
#include "Trans.h"                 /* 3D mathematics */ 
#include "LightTrack.h"           /* HW_error */ 
#include                            /* float sqrt */ 
 
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ 
 * INTERNAL: Computes square root for a long integer     * 
 * --------- using iterative bit setting.                * 
 *                                                       * 
 * RETURNS: The square root.                             * 
 * --------                                              * 
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 
 
#if defined(_FIXED_) 
unsigned long TI_sqrt(register unsigned long arg)    
{                                           /* using iterative method */ 
 register int i; 
 register unsigned long nprd,msk=0x8000L,val=0,prd=0; 
 
 for(i=15;i>=0;i--) 
 {                                          /* iteratively computing the */ 
  nprd=prd+(val<<(i+1))+(msk<>=1;                                  /* next, a lower bit */ 
 } 
 return(val); 
} 
#endif 
 
/**********************************************************\ 
 * Build a vector from two points.                        * 
 *                                                        * 
 * RETURNS: Always a pointer to the destanation.          * 
 * --------                                               * 
\**********************************************************/ 
 
int *T_vector(int *from1,int *from2,int *to,int dimension) 
{ 
 to[0]=(*from2++)-(*from1++); 
 to[1]=(*from2++)-(*from1++); 
 if(dimension==3) to[2]=(*from2)-(*from1); 
 return(to); 
} 
 
/**********************************************************\ 
 * Compute norm (length) of the vector.                   * 
 *                                                        * 
 * RETURNS: Length of the vector.                         * 
 * --------                                               * 
\**********************************************************/ 
 
long T_norm(int *vector) 
{ 
#if defined(_FLOAT_) 
 return(sqrt(((float)vector[0])*vector[0]+ 
             ((float)vector[1])*vector[1]+ 
             ((float)vector[2])*vector[2] 
            ) 
       ); 
#endif 
#if defined(_FIXED_) 
 if((vector[0]>0xffff)||(vector[1]>0xffff)||(vector[2]>0xffff)|| 
    (vector[0]<-0xffff)||(vector[1]<-0xffff)||(vector[2]<-0xffff) 
   ) 
 { 
  return(TI_sqrt(((long)vector[0]>>8)*vector[0]+ 
                 ((long)vector[1]>>8)*vector[1]+ 
                 ((long)vector[2]>>8)*vector[2] 
                )<<4                        /* to avoid an overflow: */ 
        );                                  /* sqrt(a/2**8)==sqrt(a)/2**4 */ 
 } 
 else 
 { 
  return(TI_sqrt(((long)vector[0])*vector[0]+ 
                 ((long)vector[1])*vector[1]+ 
                 ((long)vector[2])*vector[2] 
                ) 
        ); 
 } 
#endif 
} 
 
/**********************************************************\ 
 * Computing a normal through a vector product of two     * 
 * vectors.                                               * 
 *       _  _  _                                          * 
 *      |i  j  k |   _              _                     * 
 * N=det|Vx Vy Vz| = i*det|Vy Vz| - j*det|Vx Vz| +        * 
 *      |Wx Wy Wz|        |Wy Wz|        |Wx Wz|          * 
 *   _                                                    * 
 * + k*det|Vx Vy|                                         * 
 *        |Wx Wy|                                         * 
 *                                                        * 
\**********************************************************/ 
 
void T_normal_vectors(int *v,int *w,int *to) 
{ 
 int n[3]; 
 long lng; 
 
 n[0]=v[1]*w[2]-v[2]*w[1]; 
 n[1]=v[2]*w[0]-v[0]*w[2]; 
 n[2]=v[0]*w[1]-v[1]*w[0];                  /* a vector product */ 
 
 lng=T_norm(n);                             /* vector's length */ 
 
 if(lng==0) HW_error("(Trans) Found a zero length vector."); 
 
 *to++=(int)((((long)n[0])<>T_LOG_NORMAL_SIZE 
       ); 
} 
 
/**********************************************************\ 
 * Z component of the normal.                             * 
 *                                                        * 
 * RETURNS: 1 if z component negative, 0 otherwise.       * 
 * --------                                               * 
\**********************************************************/ 
 
int T_normal_z_negative(int *from1,int *from2,int *from3) 
{ 
 return((((long)(from2[0]-from1[0]))*(from3[1]-from1[1])- 
         ((long)(from2[1]-from1[1]))*(from3[0]-from1[0]))<0 
       );                                   /* component of vector product */ 
} 
 
/**********************************************************\ 
 * Computing coeficients for a plane equation.            * 
 *                                                        * 
 *        ^ N---------+   (N)(x-x0)==0                    * 
 *        |    *x   /   Nx(x-x0)+Ny(y-y0)+Nz(z-z0)==0     * 
 *      / |  /    /                                       * 
 *    /   |/x0  /   x*Nx+y*Ny+z*Nz-(Nx*x0+Ny*y0+Nz*z0)==0 * 
 *  +----------+                                          * 
 *                                                        * 
\**********************************************************/ 
 
void T_plane(int *from1,int *from2,int *from3,int *to) 
{ 
 int n[3]; 
 T_normal_plane(from1,from2,from3,n);       /* normal based on three points */ 
 
 *to++=n[0]; *to++=n[1]; *to++=n[2];        /* plane coeficients */ 
 *to=-(from1[0]*n[0]+from1[1]*n[1]+from1[2]*n[2]); 
} 
 
/**********************************************************\ 
 * Putting vertex into a plane equation Ax+By+Cz+D        * 
 *                                                        * 
 * RETURNS: 0   if a point belongs to a plane;            * 
 * -------- "+" if a point is on the normal pointed side; * 
 *          "-" if on the other side.                     * 
\**********************************************************/ 
 
int T_vertex_on_plane(int *vertex,int *plane) 
{ 
 return(vertex[0]*plane[0]+ 
        vertex[1]*plane[1]+ 
        vertex[2]*plane[2]+ 
        plane[3] 
       ); 
} 
 
/**********************************************************/