#include "xmfract.h" #include "fractype.h" #include "macros.h" #include "helpdefs.h" #include "mpmath.h" #include "globals.h" #include "prototyp.h" #ifndef NO_IDENT #ident "$Id: three_d_lib.c,v 1.400 1995/06/20 15:39:23 darryl Exp $" #endif /* * A word about the 3D library. Even though this library supports * three dimensions, the matrices are 4x4 for the following reason. * With normal 3 dimensional vectors, translation is an ADDITION, * and rotation is a MULTIPLICATION. A vector {x,y,z} is represented * as a 4-tuple {x,y,z,1}. It is then possible to define a 4x4 * matrix such that multiplying the vector by the matrix translates * the vector. This allows combinations of translation and rotation * to be obtained in a single matrix by multiplying a translation * matrix and a rotation matrix together. Note that in the code, * vectors have three components; since the fourth component is * always 1, that value is not included in the vector variable to * save space, but the routines make use of the fourth component * (see vec_mult()). Similarly, the fourth column of EVERY matrix is * always * 0 * 0 * 0 * 1 * but currently the C version of a matrix includes this even though * it could be left out of the data structure and assumed in the * routines. Vectors are ROW vectors, and are always multiplied with * matrices FROM THE LEFT (e.g. vector*matrix). Also note the order * of indices of a matrix is matrix[row][column], and in usual C * fashion, numbering starts with 0. * * TRANSLATION MATRIX = 1 0 0 0 * 0 1 0 0 * 0 0 1 0 * Tx Ty Tz 1 * * SCALE MATRIX = Sx 0 0 0 * 0 Sy 0 0 * 0 0 Sz 0 * 0 0 0 1 * * Rotation about x axis i degrees: * * ROTX(i) = 1 0 0 0 * 0 cosi sini 0 * 0 -sini cosi 0 * 0 0 0 1 * * Rotation about y axis i degrees: * ROTY(i) = cosi 0 -sini 0 * 0 1 0 0 * sini 0 cosi 0 * 0 0 0 1 * * Rotation about z axis i degrees: * ROTZ(i) = cosi sini 0 0 * -sini cosi 0 0 * 0 0 1 0 * 0 0 0 1 * * -- Tim Wegner April 22, 1989 */ /* * initialize a matrix and set to identity matrix * (all 0's, 1's on diagonal) */ void identity(MATRIX m) { int i,j; for(i=0;i FLT_MAX) return(-1); vlength = sqrt(vlength); if(vlength < FLT_MIN) return(-1); v[0] /= vlength; v[1] /= vlength; v[2] /= vlength; return(0); } /* multiply source vector s by matrix m, result in target t */ /* used to apply transformations to a vector */ int vmult(s,m,t) VECTOR s,t; MATRIX m; { VECTOR tmp; int i,j; for(j=0;j= 0.0) { v[0] = bad_value; /* clipping will catch these values */ v[1] = bad_value; /* so they won't plot values BEHIND viewer */ v[2] = bad_value; return(-1); } v[0] = (v[0]*view[2] - view[0]*v[2])/denom; v[1] = (v[1]*view[2] - view[1]*v[2])/denom; return(0); } /* long version of vmult and perspective combined for speed */ int longvmultpersp(s, m, t0, t, lview, bitshift) LVECTOR s; /* source vector */ LMATRIX m; /* transformation matrix */ LVECTOR t0; /* after transformation, before persp */ LVECTOR t; /* target vector */ LVECTOR lview; /* perspective viewer coordinates */ int bitshift; /* fixed point conversion bitshift */ { LVECTOR tmp; int i,j, k; overflow = 0; k = CMAX-1; /* shorten the math if non-perspective and non-illum */ if (lview[2] == 0 && t0[0] == 0) k--; for(j=0;j= 0) /* bail out if point is "behind" us */ { t[0] = bad_value; t[0] = t[0]<= 0) /* bail out if point is "behind" us */ { lv[0] = bad_value; lv[0] = lv[0]<