-+-+-+-+-+-+-+-+ START OF PART 265 -+-+-+-+-+-+-+-+ X\rightarrow X X \left( \begin`7Barray`7D`7Bcccc`7D X a & b & 0 & c\\ X d & e & 0 & f\\ X`09 0 & 0 & 1 & 0\\ X g & h & 0 & j X \end`7Barray`7D \right)`20 X$$`7D X*/ X`7B X ptk_unitmatrix3(mat3); X mat3`5B0`5D`5B0`5D = mat`5B0`5D`5B0`5D; /* a */ X mat3`5B0`5D`5B1`5D = mat`5B0`5D`5B1`5D; /* b */ X mat3`5B1`5D`5B0`5D = mat`5B1`5D`5B0`5D; /* d */ X mat3`5B1`5D`5B1`5D = mat`5B1`5D`5B1`5D; /* e */ X mat3`5B0`5D`5B3`5D = mat`5B0`5D`5B2`5D; /* c */ X mat3`5B1`5D`5B3`5D = mat`5B1`5D`5B2`5D; /* f */ X mat3`5B3`5D`5B0`5D = mat`5B2`5D`5B0`5D; /* g */ X mat3`5B3`5D`5B1`5D = mat`5B2`5D`5B1`5D; /* h */ X mat3`5B3`5D`5B3`5D = mat`5B2`5D`5B2`5D; /* j */`20 X`7D /* ptk_matrixtomatrix3 */ X X/*-------------------------------------------------------------------------- V--*/ X X/*function:external*/ Xextern void ptk_outputmatrix3(C(FILE *) fileptr, C(Pmatrix3) matrix,`20 X C(Pchar *) string) XPreANSI(FILE *fileptr) XPreANSI(Pmatrix3 matrix) XPreANSI(Pchar *string) X/* X** \parambegin X** \param`7BFILE *`7D`7Bfileptr`7D`7Bfile pointer`7D`7BOUT`7D X** \param`7BPmatrix3`7D`7Bmatrix`7D`7B4x4 matrix`7D`7BIN`7D X** \param`7BPchar *`7D`7Bstring`7D`7Bcharacter string`7D`7BIN`7D X** \paramend X** \blurb`7BThis function outputs the $3\times 3$ matrix X** \pardesc`7Bmatrix`7D and the message \pardesc`7Bstring`7D X** to the file specified by \pardesc`7Bfileptr`7D.`7D X*/ X`7B X Pint ii; X X /* Output Title */ X fprintf(fileptr,"\n*************************************************\n"); X fprintf(fileptr,"%s\n", string); X fprintf(fileptr," 1 2 3 4\n"); X fprintf(fileptr,"-------------------------------------------------\n"); X for (ii = 0; ii <= 3; ii++) X fprintf(fileptr,"%2ld `7C %11.4f%11.4f%11.4f%11.4f\n", X`09 ii + 1, matrix`5Bii`5D`5B0`5D, matrix`5Bii`5D`5B1`5D, matrix`5Bii`5D` V5B2`5D,`20 X matrix`5Bii`5D`5B3`5D); X fprintf(fileptr,"\n*************************************************\n"); X`7D /* ptk_outputmatrix3 */ X X/*-------------------------------------------------------------------------- V*/ X Xstatic ptkboolean validbounds3(C(Plimit3 *) bound) XPreANSI(Plimit3 *bound) X/* X** \parambegin X** \param`7BPint`7D`7B`7D`7B`7D`7BIN`7D X** \paramend X** description: checks if bounding box is sensibly defined (the min value X** is less than max value in each axis). X** input params: bound - 3D bounding box. X** output params: none. X** return value: TRUE if bounding box is valid, otherwise FALSE. X*/ X`7B X return ((bound->xmin <= bound->xmax) && (bound->ymin <= bound->ymax) && X`09 (bound->zmin <= bound->zmax)); X`7D /* validbounds3 */ X X/*-------------------------------------------------------------------------- V*/ X Xstatic ptkboolean validbounds(C(Plimit *) bound) XPreANSI(Plimit *bound) X/* X** \parambegin X** \param`7BPint`7D`7B`7D`7B`7D`7BIN`7D X** \paramend X** description: checks if bounding box is sensibly defined (the min value X** is less than max value in each axis). X** input params: bound - 3D bounding box. X** output params: none. X** return value: TRUE if bounding box is valid, otherwise FALSE. X*/ X`7B X return ((bound->xmin <= bound->xmax) && (bound->ymin <= bound->ymax)); X`7D /* validbounds */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern void ptk_box3tobox3(C(Plimit3 *) box1, C(Plimit3 *) box2,`20 X C(ptkboolean) preserve, C(Pcomptype) operation,`2 V0 X C(Pmatrix3) matrix, C(Pint *)error) XPreANSI(Plimit3 *box1) XPreANSI(Plimit3 *box2) XPreANSI(ptkboolean preserve) XPreANSI(Pcomptype operation)`20 XPreANSI(Pmatrix3 matrix) XPreANSI(Pint *error) X/* X** \parambegin X** \param`7BPlimit3 *`7D`7Bbox1`7D`7B3D volume`7D`7BIN`7D X** \param`7BPlimit3 *`7D`7Bbox2`7D`7B3D volume`7D`7BIN`7D X** \param`7Bptkboolean`7D`7Bpreserve`7D`7Bpreserve aspect ratio`7D`7BIN`7D X** \param`7BPcomptype`7D`7Boperation`7D`7Bconcatenation operation`7D`7BIN`7D X** \param`7BPmatrix3`7D`7Bmatrix`7D`7B4x4 matrix`7D`7BOUT`7D X** \param`7BPint *`7D`7Berror`7D`7Berror code`7D`7BOUT`7D X** \paramend X** \blurb`7BThis function computes a mapping from one 3D X** box to another -- a 3D window to 3D viewport X** transformation -- and concatenates this transformation X** with \pardesc`7Bmatrix`7D on the X** basis of \pardesc`7Boperation`7D.If the parameters are invalid, X** \pardesc`7Berror`7D is set to`20 X** -1. Otherwise, its value is \pardesc`7Bptkcpcok`7D.`7D X*/ X`7B X Ppoint3 vpscale, winscale; X Pmatrix3 temp; X Ppoint3 winmin, winmax, vpmin, vpmax, wincentre, vpcentre; X Pfloat minscale; X X *error = ptkcpcok; /* assume OK */ X if (!validbounds3(box1))`20 X `7B X *error = -1; X return; X `7D X winmin = ptk_point3(box1->xmin, box1->ymin, box1->zmin); X winmax = ptk_point3(box1->xmax, box1->ymax, box1->zmax); X vpmin = ptk_point3(box2->xmin, box2->ymin, box2->zmin); X vpmax = ptk_point3(box2->xmax, box2->ymax, box2->zmax); X X winscale = ptk_subv3(&winmax, &winmin); X wincentre = ptk_scalev3(&winscale, 0.5); X wincentre = ptk_addv3(&winmin, &wincentre); X wincentre = ptk_scalev3(&wincentre, -1.0); X vpscale = ptk_subv3(&vpmax, &vpmin); X vpcentre = ptk_scalev3(&vpscale, 0.5); X vpcentre = ptk_addv3(&vpmin, &vpcentre); X if (winscale.x == 0.0) X winscale.x = 1.0; X else X winscale.x = vpscale.x / winscale.x; X if (winscale.y == 0.0) X winscale.y = 1.0; X else X winscale.y = vpscale.y / winscale.y; X if (winscale.z == 0.0) X winscale.z = 1.0; X else X winscale.z = vpscale.z / winscale.z; X if (preserve) X `7B X minscale = MIN(winscale.x, winscale.y); X minscale = MIN(minscale, winscale.z); X winscale = ptk_point3(minscale, minscale, minscale); X `7D X ptk_shift3(&vpcentre, PREPLACE, temp); X ptk_scale3(&winscale, PPRECONCATENATE, temp); X ptk_shift3(&wincentre, PPRECONCATENATE, temp); X ptk_concatenatematrix3(operation, temp, matrix, matrix); X`7D /* ptk_box3tobox3 */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern void ptk_boxtobox(C(Plimit *) box1, C(Plimit *) box2,`20 X C(ptkboolean) preserve, C(Pcomptype) operation,`2 V0 X C(Pmatrix) matrix, C(Pint *)error) XPreANSI(Plimit *box1) XPreANSI(Plimit *box2) XPreANSI(ptkboolean preserve) XPreANSI(Pcomptype operation)`20 XPreANSI(Pmatrix matrix) XPreANSI(Pint *error) X/* X** \parambegin X** \param`7BPlimit *`7D`7Bbox1`7D`7B2D box`7D`7BIN`7D X** \param`7BPlimit *`7D`7Bbox2`7D`7B2D box`7D`7BIN`7D X** \param`7Bptkboolean`7D`7Bpreserve`7D`7Bpreserve aspect ratio`7D`7BIN`7D X** \param`7BPcomptype`7D`7Boperation`7D`7Bconcatenation operation`7D`7BIN`7D X** \param`7BPmatrix`7D`7Bmatrix`7D`7B3x3 matrix`7D`7BOUT`7D X** \param`7BPint *`7D`7Berror`7D`7Berror code`7D`7BOUT`7D X** \paramend X** \blurb`7BThis function computes X** a mapping from one 2D box to another -- a 2D window to 2D viewport X** transformation ---and concatenates this transformation X** it with \pardesc`7Bmatrix`7D on the X** basis of \pardesc`7Boperation`7D. X** If the parameters are invalid, \pardesc`7Berror`7D is set to`20 X** -1. Otherwise, its value is \pardesc`7Bptkcpcok`7D.`7D X*/ X`7B X Ppoint vpscale, winscale; X Pmatrix temp; X Ppoint winmin, winmax, vpmin, vpmax, wincentre, vpcentre; X Pfloat minscale; X X *error = ptkcpcok; /* assume OK */ X if (!validbounds(box1))`20 X `7B X *error = -1; X return; X `7D X winmin = ptk_point(box1->xmin, box1->ymin); X winmax = ptk_point(box1->xmax, box1->ymax); X vpmin = ptk_point(box2->xmin, box2->ymin); X vpmax = ptk_point(box2->xmax, box2->ymax); X X winscale = ptk_subv(&winmax, &winmin); X wincentre = ptk_scalev(&winscale, 0.5); X wincentre = ptk_addv(&winmin, &wincentre); X wincentre = ptk_scalev(&wincentre, -1.0); X vpscale = ptk_subv(&vpmax, &vpmin); X vpcentre = ptk_scalev(&vpscale, 0.5); X vpcentre = ptk_addv(&vpmin, &vpcentre); X if (winscale.x == 0.0) X winscale.x = 1.0; X else X winscale.x = vpscale.x / winscale.x; X if (winscale.y == 0.0) X winscale.y = 1.0; X else X winscale.y = vpscale.y / winscale.y; X if (preserve) X `7B X minscale = MIN(winscale.x, winscale.y); X winscale = ptk_point(minscale, minscale); X `7D X ptk_shift(&vpcentre, PREPLACE, temp); X ptk_scale(&winscale, PPRECONCATENATE, temp); X ptk_shift(&wincentre, PPRECONCATENATE, temp); X ptk_concatenatematrix(operation, temp, matrix, matrix); X`7D /* ptk_boxtobox */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern void ptk_accumulatetran3(C(Ppoint3 *) fixed, C(Ppoint3 *) shift,`20 X C(Pfloat) rotx, C(Pfloat) roty,`20 X C(Pfloat) rotz, C(Ppoint3 *) scale,`20 X C(Pcomptype) operation,`20 X C(Pmatrix3) matrix) XPreANSI(Ppoint3 *fixed) XPreANSI(Ppoint3 *shift)`20 XPreANSI(Pfloat rotx) XPreANSI(Pfloat roty) XPreANSI(Pfloat rotz)`20 XPreANSI(Ppoint3 *scale) XPreANSI(Pcomptype operation)`20 XPreANSI(Pmatrix3 matrix) X/* X** \parambegin X** \param`7BPpoint3 *`7D`7Bfixed`7D`7Borigin`7D`7BIN`7D X** \param`7BPpoint3 *`7D`7Bshift`7D`7Bshift factor`7D`7BIN`7D X** \param`7BPfloat`7D`7Brotx`7D`7Bx rotation`7D`7BIN`7D X** \param`7BPfloat`7D`7Brotx`7D`7By rotation`7D`7BIN`7D X** \param`7BPfloat`7D`7Brotx`7D`7Bz rotation`7D`7BIN`7D X** \param`7BPpoint3 *`7D`7Bscale`7D`7Bscale factor`7D`7BIN`7D X** \param`7BPcomptype`7D`7Boperation`7D`7Bconcatenation operation`7D`7BIN`7D X** \param`7BPmatrix3`7D`7Bmatrix`7D`7B4x4 matrix`7D`7BOUT`7D X** \paramend X** \blurb`7BThis function computes the specified 3D X** shift, scale and rotate transformations, in the order`20 X** scale, rotate, shift,`20 X** and then concatenates the resulting transformation X** with the specified matrix on the basis of \pardesc`7Boperation`7D.`7D X*/ X`7B X Pmatrix3 temp; X Ppoint3 mfixed; X X mfixed = ptk_scalev3(fixed, -1.0); X ptk_shift3(shift, PREPLACE, temp); X ptk_shift3(fixed, PPRECONCATENATE, temp); X ptk_rotate3(rotx, PTKEXAXIS, PPRECONCATENATE, temp); X ptk_rotate3(roty, PTKEYAXIS, PPRECONCATENATE, temp); X ptk_rotate3(rotz, PTKEZAXIS, PPRECONCATENATE, temp); X ptk_scale3(scale, PPRECONCATENATE, temp); X ptk_shift3(&mfixed, PPRECONCATENATE, temp); X ptk_concatenatematrix3(operation, temp, matrix, matrix); X`7D /* ptk_accumulatetran3 */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern void ptk_accumulatetran(C(Ppoint *) fixed, C(Ppoint *) shift,`20 X C(Pfloat) rot, C(Ppoint *) scale,`20 X C(Pcomptype) operation,`20 X C(Pmatrix) matrix) XPreANSI(Ppoint *fixed) XPreANSI(Ppoint *shift)`20 XPreANSI(Pfloat rot) XPreANSI(Ppoint *scale) XPreANSI(Pcomptype operation)`20 XPreANSI(Pmatrix matrix) X/* X** \parambegin X** \param`7BPpoint *`7D`7Bfixed`7D`7Borigin`7D`7BIN`7D X** \param`7BPpoint *`7D`7Bshift`7D`7Bshift factor`7D`7BIN`7D X** \param`7BPfloat`7D`7Brotx`7D`7Bx rotation`7D`7BIN`7D X** \param`7BPpoint *`7D`7Bscale`7D`7Bscale factor`7D`7BIN`7D X** \param`7BPcomptype`7D`7Boperation`7D`7Bconcatenation operation`7D`7BIN`7D X** \param`7BPmatrix`7D`7Bmatrix`7D`7B3x3 matrix`7D`7BOUT`7D X** \paramend X** \blurb`7BThis function computes the specified 2D X** shift, scale and rotate transformations, in the order`20 X** scale, rotate, shift,`20 X** and then concatenates the resulting transformation X** with the specified matrix on the basis of \pardesc`7Boperation`7D.`7D X*/ X`7B X Pmatrix temp; X Ppoint mfixed; X X mfixed = ptk_scalev(fixed, -1.0); X ptk_shift(shift, PREPLACE, temp); X ptk_shift(fixed, PPRECONCATENATE, temp); X ptk_rotate(rot, PTKEXAXIS, PPRECONCATENATE, temp); X ptk_scale(scale, PPRECONCATENATE, temp); X ptk_shift(&mfixed, PPRECONCATENATE, temp); X ptk_concatenatematrix(operation, temp, matrix, matrix); X`7D /* ptk_accumulatetran */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern void ptk_evalvieworientation3(C(Ppoint3 *) viewrefpoint,`20 X C(Ppoint3 *) viewplanenormal, X`09`09`09`09 C(Ppoint3 *) viewupvector,`20 X C(Pcomptype) operation,`20 X C(Pmatrix3) matrix, C(Pint *)error) XPreANSI(Ppoint3 *viewrefpoint) XPreANSI(Ppoint3 *viewplanenormal) XPreANSI(Ppoint3 *viewupvector) XPreANSI(Pcomptype operation)`20 XPreANSI(Pmatrix3 matrix) XPreANSI(Pint *error) X/* X** \parambegin X** \param`7BPpoint3 *`7D`7Bviewrefpoint`7D`7Bview reference point`7D`7BIN`7D X** \param`7BPpoint3 *`7D`7Bviewplanenormal`7D`7Bview plane normal`7D`7BIN`7D X** \param`7BPpoint3 *`7D`7Bviewupvector`7D`7Bview up vector`7D`7BIN`7D X** \param`7BPcomptype`7D`7Boperation`7D`7Bconcatenation operation`7D`7BIN`7D X** \param`7BPmatrix3`7D`7Bmatrix`7D`7B4x4 matrix`7D`7BOUT`7D X** \param`7BPint *`7D`7Berror`7D`7Berror code`7D`7BOUT`7D X** \paramend X** \blurb`7BThis function computes`20 X** a 3D PHIGS view orientation matrix on the basis of X** a specified view reference point (\pardesc`7Bviewrefpoint`7D), a X** view plane normal (\pardesc`7Bviewplanenormal`7D) and a view up vector X** (\pardesc`7Bviewupvector`7D). If the function succeeds, X** \pardesc`7Berror`7D is set to`20 X** \pardesc`7Bptkcpcok`7D. Otherwise, X** \pardesc`7Berror`7D is 61 if the view plane normal is null, X** 63 if the view up vector is null, X** and 58 if the cross product of the view up vector X** and the view plane normal is null.`7D X*/ X`7B X Ppoint3 uaxis, vaxis, naxis, vuvxvpn; X Pmatrix3 temp; X X *error = ptkcpcok; X if (ptk_nullv3(viewplanenormal))`20 X `7B X *error = 61; X `7D`20 X else`20 X if (ptk_nullv3(viewupvector))`20 X `7B X *error = 63; X `7D`20 X else`20 X `7B X vuvxvpn = ptk_crossv3(viewupvector, viewplanenormal); X if (ptk_nullv3(&vuvxvpn)) X *error = 58; X else X *error = ptkcpcok; X `7D X if (*error != ptkcpcok)`20 X `7B X return; X `7D /* if error = 0 */ X /* generate from viewplanenormal and viewupvector a set +-+-+-+-+-+-+-+- END OF PART 265 +-+-+-+-+-+-+-+-