home *** CD-ROM | disk | FTP | other *** search
- (******************************************************************************
- * Ctm3d *
- ******************************************************************************)
- Unit Ctm3d;
-
- (*******************************************************************************
- * Homogeneous Coordinates *
- * ----------------------- *
- * *
- * Homogeneous coordinates allow transformations to be represented by *
- * matrices. A 3x3 matrix is used for 2D transformations, and a 4x4 matrix*
- * for 3D transformations. *
- * *
- * THIS MODULE IMPLEMENTS ONLY 3D TRANSFORMATIONS. *
- * *
- * in homogeneous coordination the point P(x,y,z) is represented as *
- * P(w*x, w*y, w*z, w) for any scale factor w!=0. *
- * in this module w == 1. *
- * *
- * Transformations: *
- * 1. translation *
- * [x, y, z] --> [x + Dx, y + Dy, z + Dz] *
- * *
- * ┌ ┐ *
- * │1 0 0 0│ *
- * T(Dx, Dy, Dz) = │0 1 0 0│ *
- * │0 0 1 0│ *
- * │Dx Dy Dz 1│ *
- * └ ┘ *
- * 2. scaling *
- * [x, y, z] --> [Sx * x, Sy * y, Sz * z] *
- * *
- * ┌ ┐ *
- * │Sx 0 0 0│ *
- * S(Sx, Sy) = │0 Sy 0 0│ *
- * │0 0 Sz 0│ *
- * │0 0 0 1│ *
- * └ ┘ *
- * *
- * 3. rotation *
- * *
- * a) Around the Z axis: *
- * *
- * [x, y, z] --> [x*cost - t*sint, x*sint + y*cost, z] *
- * ┌ ┐ *
- * │cost sint 0 0│ *
- * Rz(t) = │-sint cost 0 0│ *
- * │0 0 1 0│ *
- * │0 0 0 1│ *
- * └ ┘ *
- * *
- * b) Around the X axis: *
- * *
- * [x, y, z] --> [x, y*cost - z*sint, y*sint + z*cost] *
- * ┌ ┐ *
- * │1 0 0 0│ *
- * Rx(t) = │0 cost sint 0│ *
- * │0 -sint cost 0│ *
- * │0 0 0 1│ *
- * └ ┘ *
- * *
- * c) Around the Y axis: *
- * *
- * [x, y, z] --> [xcost + z*sint, y, z*cost - x*sint] *
- * ┌ ┐ *
- * │cost 0 -sint 0│ *
- * Ry(t) = │0 1 0 0│ *
- * │sint 0 cost 0│ *
- * │0 0 0 1│ *
- * └ ┘ *
- * *
- * transformation of the vector [x,y,z,1] by transformation matrix T is given *
- * by the formula: *
- * ┌ ┐ *
- * [x', y', z', 1] = [x,y,z,1]│ T │ *
- * └ ┘ *
- * Optimizations: *
- * The most general composition of R, S and T operations will produce a matrix*
- * of the form: *
- * ┌ ┐ *
- * │r11 r12 r13 0│ *
- * │r21 r22 r23 0│ *
- * │r31 r32 r33 0│ *
- * │tx ty tz 1│ *
- * └ ┘ *
- * The task of matrix multiplication can be simplified by *
- * x' = x*r11 + y*r21 + z*r31 + tx *
- * y' = x*r12 + y*r22 + z*r32 + ty *
- * z' = x*r13 + y*r23 + z*r33 + tz *
- * *
- * *
- * See also: *
- * "Fundamentals of Interactive Computer Graphics" J.D FOLEY A.VAN DAM *
- * Adison-Weslely ISBN 0-201-14468-9 pp 245-265 *
- *******************************************************************************)
-
- interface
-
- uses hdr3d;
-
- type
- ctmPtr = ^ctm;
- ctm = object
- r11, r12, r13 : real;
- r21, r22, r23 : real;
- r31, r32, r33 : real;
- tx, ty, tz : real;
-
- constructor SetUnit;
- constructor Copy(var src : ctm);
- procedure save(var dest : ctm);
-
- procedure translate(Dx, Dy, Dz : real);
-
- procedure translateX(dx : real);
- procedure translateY(dy : real);
- procedure translateZ(dz : real);
- {use these routines for single axis translations, they are faster!}
-
- procedure rotateX(t : real);
- procedure rotateY(t : real);
- procedure rotateZ(t : real);
-
- procedure scale(Sx, Sy, Sz : real);
-
- procedure scaleX(sx : real);
- procedure scaleY(sy : real);
- procedure scaleZ(sz : real);
- {use these routines for single axis scaling, they are faster!!!}
-
- procedure Left_translate(Dx, Dy, Dz : real);
-
- procedure Left_translateX(dx : real);
- procedure Left_translateY(dy : real);
- procedure Left_translateZ(dz : real);
- {use theseLeft_ routines for single axis translations, they are faster!}
-
- procedure Left_rotateX(t : real);
- procedure Left_rotateY(t : real);
- procedure Left_rotateZ(t : real);
-
- procedure Left_scale(Sx, Sy, Sz : real);
-
- procedure Left_scaleX(sx : real);
- procedure Left_scaleY(sy : real);
- procedure Left_scaleZ(sz : real);
- {use these routines for single axis scaling, they are faster!!!}
-
- procedure transform(var t: point3d; p : point3d);
- {
- Note that t (target) is var, but p is NOT.
- p cannot be a var parameter, because if the same point is
- transformed, data should be copied for correct results
- }
- procedure inv_transform(var p : point3d);
- { inv_transform changes the input point }
-
- procedure inverse; { M ^-1 }
- procedure multiply(var c : ctm); {multiply from right self * c}
- procedure Multiply_2(var a, b : ctm);
- end;
-
- implementation
-
- (*---------------------------------------------------------------------------
- * ctm.SetUnit -- set the ctm to the unit matrix.
- *---------------------------------------------------------------------------
- *)
- constructor ctm.SetUnit;
- begin
- r11 := 1; r12 := 0; r13 := 0;
- r21 := 0; r22 := 1; r23 := 0;
- r31 := 0; r32 := 0; r33 := 1;
- Tx := 0; Ty := 0; Tz := 0;
- end;
-
- (*---------------------------------------------------------------------------
- * ctm.Copy -- Copy another ctm to self.
- *---------------------------------------------------------------------------
- *)
- constructor ctm.copy;
- begin
- { This copy is done this way instead of
- Self := Src; becuase TP does not do that as expected. }
-
- r11 := Src.r11;
- r12 := Src.r12;
- r13 := Src.r13;
- r21 := Src.r21;
- r22 := Src.r22;
- r23 := Src.r23;
- r31 := Src.r31;
- r32 := Src.r32;
- r33 := Src.r33;
- tx := Src.tx;
- ty := Src.ty;
- tz := Src.tz;
- end;
-
- (* ctm.save save ctm in a specified variable ctm *)
- (*******************************************************************************
- * ctm.save *
- *******************************************************************************)
- procedure ctm.save;
- begin
- dest := self;
- end;
-
- (*---------------------------------------------------------------------------
- * ctm.translate -- multyply ctm by T(dx,dy,dz). ctm = ctm * T(dx,dy,dz)
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │r11 r12 r13 0│ │1 0 0 0│ │r11 r12 r31 0│
- * │r21 r22 r23 0│ * │0 1 0 0│ = │r21 r22 r31 0│
- * │r31 r32 r33 0│ │0 0 1 0│ │r21 r22 r31 0│
- * │tx ty tz 1│ │Dx Dy Dz 1│ │tx' ty' tz' 1│
- * └ ┘ └ ┘ └ ┘
- *
- * tx' = tx + Dx
- * ty' = ty + Dy
- * tz' = tz + Dz
- *---------------------------------------------------------------------------
- *)
- procedure ctm.translate;
- begin
- Tx := Tx + Dx;
- Ty := Ty + Dy;
- Tz := Tz + Dz;
- end;
-
-
- (*---------------------------------------------------------------------------
- * ctm.Left_translate -- multyply ctm by T(dx,dy,dz) on the left.
- * ctm = T(dx,dy,dz) * ctm
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │1 0 0 0│ │r11 r12 r13 0│ │r11 r12 r31 0│
- * │0 1 0 0│ │r21 r22 r23 0│ = │r21 r22 r31 0│
- * │0 0 1 0│ │r31 r32 r33 0│ │r21 r22 r31 0│
- * │Dx Dy Dz 1│ │tx ty tz 1│ │tx' ty' tz' 1│
- * └ ┘ └ ┘ └ ┘
- *
- * tx' = r11 * Dx + r21 * Dy + r31 * Dz + tx
- * ty' = r12 * Dx + r22 * Dy + r32 * Dz + ty
- * tz' = r13 * Dx + r23 * Dy + r33 * Dz + tz
- *---------------------------------------------------------------------------
- *)
- procedure ctm.Left_translate;
- begin
- Tx := Tx + r11 * Dx + r21 * Dy + r31 * Dz;
- Ty := Ty + r12 * Dx + r22 * Dy + r32 * Dz;
- Tz := Tz + r13 * Dx + r23 * Dy + r33 * Dz;
- end;
-
-
- (*******************************************************************************
- * ctm.translateX *
- *******************************************************************************)
- procedure ctm.translateX;
- begin
- tx := tx+dx;
- end;
-
- (*******************************************************************************
- * ctm.Left_translateX *
- *******************************************************************************)
- procedure ctm.Left_translateX;
- begin
- tx := tx + dx * r11;
- ty := ty + dx * r12;
- tz := tz + dx * r13;
- end;
-
- (*******************************************************************************
- * ctm.translateY *
- *******************************************************************************)
- procedure ctm.translateY;
- begin
- ty := ty+dy;
- end;
-
- (*******************************************************************************
- * ctm.Left_translateY *
- *******************************************************************************)
- procedure ctm.Left_translateY;
- begin
- tx := tx + dy * r21;
- ty := ty + dy * r22;
- tz := tz + dy * r23;
- end;
-
-
- (*******************************************************************************
- * ctm.translateZ *
- *******************************************************************************)
- procedure ctm.translateZ;
- begin
- tz := tz+dz;
- end;
-
- (*******************************************************************************
- * ctm.Left_translateZ *
- *******************************************************************************)
- procedure ctm.Left_translateZ;
- begin
- tx := tx + dz * r31;
- ty := ty + dz * r32;
- tz := tz + dz * r33;
- end;
-
-
- {the above 6 procedures are used for single axis translation - # of FP
- operations is 1/3, # of arguments passed is 1/3, try using these
- procedures when possiable to improve animation}
-
- (*---------------------------------------------------------------------------
- * ctm.scale -- multyply ctm by S(sx,sy,sz). ctm = ctm * S(sx,sy,sz)
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │r11 r12 r13 0│ │Sx 0 0 0│ │Sx*r11 Sy*r12 Sz*r13 0│
- * │r21 r22 r23 0│ * │0 Sy 0 0│ = │Sx*r21 Sy*r22 Sz*r13 0│
- * │r31 r32 r33 0│ │0 0 Sz 0│ │Sx*r31 Sy*r32 Sz*r33 0│
- * │tx ty tz 1│ │0 0 0 1│ │Sx*tx Sy*ty Sz*tz 1│
- * └ ┘ └ ┘ └ ┘
- *---------------------------------------------------------------------------
- *)
- procedure ctm.scale;
- begin
- r11 := r11*Sx; r12 := r12*Sy; r13 := r13*Sz;
- r21 := r21*Sx; r22 := r22*Sy; r23 := r23*Sz;
- r31 := r31*Sx; r32 := r32*Sy; r33 := r33*Sz;
- tx := tx*Sx; ty := ty*Sy; tz := tz*Sz
- end;
-
-
- (*---------------------------------------------------------------------------
- * ctm.Left_scale -- multyply ctm by S(sx,sy,sz) on the left.
- * ctm = S(sx,sy,sz) * ctm
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │Sx 0 0 0│ │r11 r12 r13 0│ │Sx*r11 Sy*r12 Sz*r13 0│
- * │0 Sy 0 0│ * │r21 r22 r23 0│ = │Sx*r21 Sy*r22 Sz*r13 0│
- * │0 0 Sz 0│ │r31 r32 r33 0│ │Sx*r31 Sy*r32 Sz*r33 0│
- * │0 0 0 1│ │tx ty tz 1│ │ tx ty tz 1│
- * └ ┘ └ ┘ └ ┘
- *---------------------------------------------------------------------------
- *)
- procedure ctm.Left_scale;
- begin
- r11 := r11*Sx; r12 := r12*Sy; r13 := r13*Sz;
- r21 := r21*Sx; r22 := r22*Sy; r23 := r23*Sz;
- r31 := r31*Sx; r32 := r32*Sy; r33 := r33*Sz;
- end;
-
-
- (*******************************************************************************
- * ctm.scaleZ *
- *******************************************************************************)
- procedure ctm.scaleZ;
- begin
- r13 := r13*Sz;
- r23 := r23*Sz;
- r33 := r33*Sz;
- tz := tz*Sz;
- end;
-
- (*******************************************************************************
- * ctm.Left_scaleZ *
- *******************************************************************************)
- procedure ctm.Left_scaleZ;
- begin
- r31 := r31*Sz;
- r32 := r32*Sz;
- r33 := r33*Sz;
- end;
-
-
- (*******************************************************************************
- * ctm.scaleY *
- *******************************************************************************)
- procedure ctm.scaleY;
- begin
- r12 := r12*Sy;
- r22 := r22*Sy;
- r32 := r32*Sy;
- ty := ty*Sy;
- end;
-
- (*******************************************************************************
- * ctm.Left_scaleY *
- *******************************************************************************)
- procedure ctm.Left_scaleY;
- begin
- r21 := r21*Sy;
- r22 := r22*Sy;
- r23 := r23*Sy;
- end;
-
- (*******************************************************************************
- * ctm.scaleX *
- *******************************************************************************)
- procedure ctm.scaleX;
- begin
- r11 := r11*Sx;
- r21 := r21*Sx;
- r31 := r31*Sx;
- tx := tx*Sx;
- end;
-
- (*******************************************************************************
- * ctm.Left_scaleX *
- *******************************************************************************)
- procedure ctm.Left_scaleX;
- begin
- r11 := r11*Sx;
- r12 := r12*Sx;
- r13 := r13*Sx;
- end;
-
-
- {the above 6 routines should be used for single axis scale, they are much
- faster then calling the general scale routine (with a factor of
- better then 3), and require less arguments}
-
-
- (*---------------------------------------------------------------------------
- * ctm.rotateZ -- multyply ctm by Rz(t). ctm = ctm * Rz(t)
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │r11 r12 r13 0│ │cost sint 0 0│ │r11' r12' r13 0│
- * │r21 r22 r23 0│ │-sint cost 0 0│ │r21' r22' r23 0│
- * │r31 r32 r33 0│ * │0 0 1 0│ = │r31' r32' r33 0│
- * │tx ty tz 1│ │0 0 0 1│ │tx' ty' tz 1│
- * └ ┘ └ ┘ └ ┘
- *
- * r11' = r11*cost - r12*sint
- * r21' = r21*cost - r22*sint
- * r31' = r31*cost - r32*sint
- * tx' = tx *cost - ty *sint
- * r12' = r11*sint + r12*cost
- * r22' = r21*sint + r22*cost
- * r32' = r31*sint + r32*cost
- * ty' = tx *sint + ty *cost
- *
- *---------------------------------------------------------------------------
- *)
- procedure ctm.rotateZ;
- var
- cost, sint : real;
- tmp : real;
- begin
- cost := cos(t / 180.0 * 3.1415926535897932385);
- sint := sin(t / 180.0 * 3.1415926535897932385);
-
- tmp := r11*cost - r12*sint;
- r12 := r11*sint + r12*cost;
- r11 := tmp;
- tmp := r21*cost - r22*sint;
- r22 := r21*sint + r22*cost;
- r21 := tmp;
- tmp := r31*cost - r32*sint;
- r32 := r31*sint + r32*cost;
- r31 := tmp;
- tmp := tx *cost - ty *sint;
- ty := tx *sint + ty *cost;
- tx := tmp;
- end;
-
- (*---------------------------------------------------------------------------
- * ctm.Left_rotateZ -- multyply ctm by Rz(t) on the left. ctm = Rz(t) * ctm
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │cost sint 0 0│ │r11 r12 r13 0│ │r11' r12' r13' 0│
- * │-sint cost 0 0│ │r21 r22 r23 0│ │r21' r22' r23' 0│
- * │0 0 1 0│ * │r31 r32 r33 0│ = │r31 r32 r33 0│
- * │0 0 0 1│ │tx ty tz 1│ │tx ty tz 1│
- * └ ┘ └ ┘ └ ┘
- *
- * r11' = r11*cost + r21*sint
- * r12' = r12*cost + r22*sint
- * r13' = r13*cost + r23*sint
- * r21' = r21*cost - r11*sint
- * r22' = r22*cost - r12*sint
- * r23' = r23*cost - r13*sint
- *
- *---------------------------------------------------------------------------
- *)
- procedure ctm.Left_rotateZ;
- var
- cost, sint : real;
- tmp : real;
- begin
- cost := cos(t / 180.0 * 3.1415926535897932385);
- sint := sin(t / 180.0 * 3.1415926535897932385);
-
- tmp := r11 * cost + r21 * sint;
- r21 := r21 * cost - r11 * sint;
- r11 := tmp;
- tmp := r12 * cost + r22 * sint;
- r22 := r22 * cost - r12 * sint;
- r12 := tmp;
- tmp := r13 * cost + r23 * sint;
- r23 := r23 * cost - r13 * sint;
- r13 := tmp;
- end;
-
- (*---------------------------------------------------------------------------
- * ctm.rotateX -- multyply ctm by Rx(t). ctm = ctm * Rx(t)
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │r11 r12 r13 0│ │1 0 0 0│ │r11 r12' r13' 0│
- * │r21 r22 r23 0│ │0 cost sint 0│ │r21 r22' r23' 0│
- * │r31 r32 r33 0│ * │0 -sint cost 0│ = │r31 r32' r33' 0│
- * │tx ty tz 1│ │0 0 0 1│ │tx ty' tz' 1│
- * └ ┘ └ ┘ └ ┘
- *
- * r12' = r12*cost - r13*sint
- * r13' = r12*sint + r13*cost
- * r22' = r22*cost - r23*sint
- * r23' = r22*sint + r23*cost
- * ty' = ty *cost - tz *sint
- * tz' = ty *sint + tz *cost
- *---------------------------------------------------------------------------
- *)
- procedure ctm.rotateX;
- var
- cost, sint : real;
- tmp : real;
- begin
- cost := cos(t / 180.0 * 3.1415926535897932385); {constants are evaluated at compile time}
- sint := sin(t / 180.0 * 3.1415926535897932385);
-
- tmp := r12*cost - r13*sint;
- r13 := r12*sint + r13*cost;
- r12 := tmp;
- tmp := r22*cost - r23*sint;
- r23 := r22*sint + r23*cost;
- r22 := tmp;
- tmp := r32*cost - r33*sint;
- r33 := r32*sint + r33*cost;
- r32 := tmp;
- tmp := ty *cost - tz *sint;
- tz := ty *sint + tz *cost;
- ty := tmp;
- end;
-
-
- (*---------------------------------------------------------------------------
- * ctm.Left_rotateX -- multyply ctm by Rx(t) on the left. ctm = Rx(t) * ctm
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │1 0 0 0│ │r11 r12 r13 0│ │r11 r12 r13 0│
- * │0 cost sint 0│ │r21 r22 r23 0│ │r21' r22' r23' 0│
- * │0 -sint cost 0│ * │r31 r32 r33 0│ = │r31' r32' r33' 0│
- * │0 0 0 1│ │tx ty tz 1│ │tx ty tz 1│
- * └ ┘ └ ┘ └ ┘
- *
- * r21' = r21*cost + r31*sint
- * r22' = r22*cost + r32*sint
- * r23' = r23*cost + r33*sint
- * r31' = r31*cost - r21*sint
- * r32' = r32*cost - r22*sint
- * r33' = r33*cost - r23*sint
- *
- *---------------------------------------------------------------------------
- *)
- procedure ctm.Left_rotateX;
- var
- cost, sint : real;
- tmp : real;
- begin
- cost := cos(t / 180.0 * 3.1415926535897932385);
- sint := sin(t / 180.0 * 3.1415926535897932385);
-
- tmp := r21 * cost + r31 * sint;
- r31 := r31 * cost - r21 * sint;
- r21 := tmp;
- tmp := r22 * cost + r32 * sint;
- r32 := r32 * cost - r22 * sint;
- r22 := tmp;
- tmp := r23 * cost + r33 * sint;
- r33 := r33 * cost - r23 * sint;
- r23 := tmp;
- end;
-
- (*---------------------------------------------------------------------------
- * ctm.rotateY -- multyply ctm by Rx(t). ctm = ctm * Ry(t)
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │r11 r12 r13 0│ │cost 0 -sint 0│ │r11' r12 r13' 0│
- * │r21 r22 r23 0│ │0 1 0 0│ │r21' r22 r23' 0│
- * │r31 r32 r33 0│ * │sint 0 cost 0│ = │r31' r32 r33' 0│
- * │tx ty tz 1│ │0 0 0 1│ │tx ty' tz' 1│
- * └ ┘ └ ┘ └ ┘
- *
- * r11' = r11*cost + r13*sint
- * r13' = r13*cost - r11*sint
- * r21' = r21*cost + r23*sint
- * r23' = r23*cost - r21*sint
- * tx' = tx *cost + tz *sint
- * tz' = tz *cost - tx *sint
- *---------------------------------------------------------------------------
- *)
- procedure ctm.rotateY;
- var
- cost, sint : real;
- tmp : real;
- begin
- cost := cos(t / 180.0 * 3.1415926535897932385);
- sint := sin(t / 180.0 * 3.1415926535897932385);
-
- tmp := r11*cost + r13*sint;
- r13 := r13*cost - r11*sint;
- r11 := tmp;
- tmp := r21*cost + r23*sint;
- r23 := r23*cost - r21*sint;
- r21 := tmp;
- tmp := r31*cost + r33*sint;
- r33 := r33*cost - r31*sint;
- r31 := tmp;
- tmp := tx *cost + tz *sint;
- tz := tz *cost - tx *sint;
- tx := tmp;
- end;
-
- (*---------------------------------------------------------------------------
- * ctm.Left_rotateY -- multyply ctm by Ry(t) on the left. ctm = Ry(t) * ctm
- * ┌ ┐ ┌ ┐ ┌ ┐
- * │cost 0 -sint 0│ │r11 r12 r13 0│ │r11' r12' r13' 0│
- * │0 1 0 0│ │r21 r22 r23 0│ │r21 r22 r23 0│
- * │sint 0 cost 0│ * │r31 r32 r33 0│ = │r31' r32' r33' 0│
- * │0 0 0 1│ │tx ty tz 1│ │tx ty tz 1│
- * └ ┘ └ ┘ └ ┘
- *
- * r11' = r11*cost - r31*sint
- * r12' = r11*cost - r32*sint
- * r13' = r11*cost - r33*sint
- * r31' = r31*cost + r11*sint
- * r32' = r32*cost + r12*sint
- * r33' = r33*cost + r13*sint
- *
- *---------------------------------------------------------------------------
- *)
- procedure ctm.Left_rotateY;
- var
- cost, sint : real;
- tmp : real;
- begin
- cost := cos(t / 180.0 * 3.1415926535897932385);
- sint := sin(t / 180.0 * 3.1415926535897932385);
-
- tmp := r11 * cost - r31 * sint;
- r31 := r31 * cost + r11 * sint;
- r11 := tmp;
- tmp := r11 * cost - r32 * sint;
- r32 := r32 * cost + r12 * sint;
- r12 := tmp;
- tmp := r11 * cost - r33 * sint;
- r33 := r33 * cost + r13 * sint;
- r13 := tmp;
- end;
-
- (*---------------------------------------------------------------------------
- * ctm.transform -- transform [x,y,z] by the CTM.
- *
- * See remarks at the top.
- *---------------------------------------------------------------------------
- *)
- procedure ctm.transform;
- begin
- t.x := p.x*r11 + p.y*r21 + p.z*r31 + tx;
- t.y := p.x*r12 + p.y*r22 + p.z*r32 + ty;
- t.z := p.x*r13 + p.y*r23 + p.z*r33 + tz;
- end;
-
- (*---------------------------------------------------------------------------
- * ctm.inv_transform -- transform [x',y',z'] by the INVERS
- * transfomation CTM^-1
- *
- * The inverse transformation is calculated by solving the 3 equations
- * for x,y,z.
- *
- * x' = x*r11 + y*r21 + z*r31 + tx
- * y' = x*r12 + y*r22 + z*r32 + ty
- * z' = x*r13 + y*r23 + z*r33 + tz
- *
- *---------------------------------------------------------------------------
- *)
- procedure ctm.inv_transform;
- var
- d : real; { Delta }
- d_x : real; { Delta X [X = Delta X / Delta] }
- d_y : real; { Delta Y [Y = Delta Y / Delta] }
- d_z : real; { Delta Z [Z = Delta Z / Delta] }
- begin
- d := r11*(r22*r33 - r32*r23)
- -r21*(r12*r33 - r13*r32)
- +r31*(r12*r23 - r22*r13);
- d_x:= (p.x - tx)*(r22*r33 - r32*r23)
- -r21*((p.y - ty)*r33 - (p.z - tz)*r32)
- +r31*((p.y - ty)*r23 - r22*(p.z - tz));
- d_y:= r11*((p.y - ty)*r33 - r32*(p.z - tz))
- -(p.x - tx)*(r12*r33 - r13*r32)
- +r31*(r12*(p.z - tz) - (p.y - ty)*r13);
- d_z:= r11*(r22*(p.z - tz) - (p.y - ty)*r23)
- -r21*(r12*(p.z - tz) - r13*(p.y - ty))
- +(p.x - tx)*(r12*r23 - r22*r13);
- p.x := round(d_x / d);
- p.y := round(d_y / d);
- p.z := round(d_z / d);
- end;
-
- (*******************************************************************************
- * ctm.multiply *
- * here we multiply our ctm with another from the right : self * c -> self *
- *******************************************************************************)
- procedure ctm.multiply;
- var
- t : ctm;
- begin
- t.r11 := r11*c.r11+r12*c.r21+r13*c.r31;
- t.r21 := r21*c.r11+r22*c.r21+r23*c.r31;
- t.r31 := r31*c.r11+r32*c.r21+r33*c.r31;
- t.tx := tx *c.r11+ty *c.r21+tz *c.r31+c.tx;
-
- t.r12 := r11*c.r12+r12*c.r22+r13*c.r32;
- t.r22 := r21*c.r12+r22*c.r22+r23*c.r32;
- t.r32 := r31*c.r12+r32*c.r22+r33*c.r32;
- t.ty := tx *c.r12+ty *c.r22+tz *c.r32+c.ty;
-
- t.r13 := r11*c.r13+r12*c.r23+r13*c.r33;
- t.r23 := r21*c.r13+r22*c.r23+r23*c.r33;
- t.r33 := r31*c.r13+r32*c.r23+r33*c.r33;
- t.tz := tx *c.r13+ty *c.r23+tz *c.r33+c.tz;
-
- copy(t);
- end; {ctm.multiply}
-
- (*******************************************************************************
- * ctm.multiply_2 *
- * here we multiply our ctm with another from the right : self * c -> self *
- *******************************************************************************)
- procedure ctm.multiply_2;
- begin
- r11 := a.r11*b.r11+a.r12*b.r21+a.r13*b.r31;
- r21 := a.r21*b.r11+a.r22*b.r21+a.r23*b.r31;
- r31 := a.r31*b.r11+a.r32*b.r21+a.r33*b.r31;
- tx := a.tx *b.r11+a.ty *b.r21+a.tz *b.r31+b.tx;
-
- r12 := a.r11*b.r12+a.r12*b.r22+a.r13*b.r32;
- r22 := a.r21*b.r12+a.r22*b.r22+a.r23*b.r32;
- r32 := a.r31*b.r12+a.r32*b.r22+a.r33*b.r32;
- ty := a.tx *b.r12+a.ty *b.r22+a.tz *b.r32+b.ty;
-
- r13 := a.r11*b.r13+a.r12*b.r23+a.r13*b.r33;
- r23 := a.r21*b.r13+a.r22*b.r23+a.r23*b.r33;
- r33 := a.r31*b.r13+a.r32*b.r23+a.r33*b.r33;
- tz := a.tx *b.r13+a.ty *b.r23+a.tz *b.r33+b.tz;
- end; {ctm.multiply_2}
-
-
- (*******************************************************************************
- * ctm.inverse *
- *******************************************************************************)
- procedure ctm.inverse;
- begin
- runerror;
- end;
-
-
- end.
-