home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 9
/
CD_ASCQ_09_1193.iso
/
news
/
556
/
ctm3d.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-06-02
|
38KB
|
761 lines
(******************************************************************************
* 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; { change to single if numeric processor is present }
r21, r22, r23 : real;
r31, r32, r33 : real;
tx, ty, tz : real;
constructor SetUnit; { set to the unit (I) matrix }
constructor Copy(var src : ctm); { construct from another }
procedure save(var dest : ctm);
procedure translate(Dx, Dy, Dz : real); { used to move .. }
procedure translateX(dx : real);
procedure translateY(dy : real);
procedure translateZ(dz : real); { translate in one axis only }
{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 these Left_ 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 .Bring the matrix to (-1) power}
procedure multiply(var c : ctm); {multiply from right self * c}
procedure Multiply_2(var a, b : ctm);
end;
implementation
const
pi = 3.1415926535897932385;
(******************************************************************************
* ctm.SetUnit *
* 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.setUnit}
(******************************************************************************
* ctm.copy *
* Copy another CTM to SELF. *
* This copy is done this way because TP does not construct SELF if we perform *
* Self := SRC; *
******************************************************************************)
constructor ctm.copy;
begin
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.copy}
(*******************************************************************************
* ctm.save *
* Save CTM in specified variable CTM *
*******************************************************************************)
procedure ctm.save;
begin
dest := self;
end; {ctm.self}
(******************************************************************************
* ctm.translate *
* 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.translate}
(******************************************************************************
* ctm.Left_translate *
* 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.Left_translate}
(*******************************************************************************
* ctm.translateX *
* Notice - This procedure is FASTER then translate(dx, 0, 0) *
*******************************************************************************)
procedure ctm.translateX;
begin
tx := tx+dx;
end; {ctm.translateX}
(*******************************************************************************
* ctm.Left_translateX *
*******************************************************************************)
procedure ctm.Left_translateX;
begin
tx := tx + dx * r11;
ty := ty + dx * r12;
tz := tz + dx * r13;
end; {ctm.left_translateX}
(*******************************************************************************
* ctm.translateY *
*******************************************************************************)
procedure ctm.translateY;
begin
ty := ty+dy;
end; {ctm.translateY}
(*******************************************************************************
* ctm.Left_translateY *
*******************************************************************************)
procedure ctm.Left_translateY;
begin
tx := tx + dy * r21;
ty := ty + dy * r22;
tz := tz + dy * r23;
end; {ctm.Left_translateY}
(*******************************************************************************
* ctm.translateZ *
*******************************************************************************)
procedure ctm.translateZ;
begin
tz := tz+dz;
end; {ctm.translateZ}
(*******************************************************************************
* ctm.Left_translateZ *
*******************************************************************************)
procedure ctm.Left_translateZ;
begin
tx := tx + dz * r31;
ty := ty + dz * r32;
tz := tz + dz * r33;
end; {ctm.Left_translateZ}
(* 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 *
* 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.scale}
(******************************************************************************
* ctm.Left_scale *
* 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.left_scale}
(*******************************************************************************
* ctm.scaleZ *
*******************************************************************************)
procedure ctm.scaleZ;
begin
r13 := r13*Sz;
r23 := r23*Sz;
r33 := r33*Sz;
tz := tz*Sz;
end; {ctm.scaleZ}
(*******************************************************************************
* ctm.Left_scaleZ *
*******************************************************************************)
procedure ctm.Left_scaleZ;
begin
r31 := r31*Sz;
r32 := r32*Sz;
r33 := r33*Sz;
end; {ctm.left_scaleZ}
(*******************************************************************************
* ctm.scaleY *
*******************************************************************************)
procedure ctm.scaleY;
begin
r12 := r12*Sy;
r22 := r22*Sy;
r32 := r32*Sy;
ty := ty*Sy;
end; {ctm.scaleY}
(*******************************************************************************
* ctm.Left_scaleY *
*******************************************************************************)
procedure ctm.Left_scaleY;
begin
r21 := r21*Sy;
r22 := r22*Sy;
r23 := r23*Sy;
end; {ctm.Left_scaleY}
(*******************************************************************************
* ctm.scaleX *
*******************************************************************************)
procedure ctm.scaleX;
begin
r11 := r11*Sx;
r21 := r21*Sx;
r31 := r31*Sx;
tx := tx*Sx;
end; {ctm.scaleX}
(*******************************************************************************
* ctm.Left_scaleX *
*******************************************************************************)
procedure ctm.Left_scaleX;
begin
r11 := r11*Sx;
r12 := r12*Sx;
r13 := r13*Sx;
end; {ctm.Left_scaleX}
(* 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 *
* 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 * pi);
sint := sin(t / 180.0 * pi);
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.rotateZ}
(******************************************************************************
* ctm.Left_rotateZ *
* 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 * pi);
sint := sin(t / 180.0 * pi);
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.Left_rotateZ}
(******************************************************************************
* ctm.rotateX *
* 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 * pi); {constants are evaluated at compile time}
sint := sin(t / 180.0 * pi);
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.rotateX}
(******************************************************************************
* ctm.Left_rotateX *
* 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 * pi);
sint := sin(t / 180.0 * pi);
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.Left_rotateX}
(******************************************************************************
* ctm.rotateY *
* 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 * pi);
sint := sin(t / 180.0 * pi);
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.rotateY}
(******************************************************************************
* ctm.Left_rotateY *
* 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 * pi);
sint := sin(t / 180.0 * pi);
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.Left_rotateY}
(******************************************************************************
* ctm.transform *
* 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.transform}
(******************************************************************************
* ctm.inv_transform *
* 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.inv_transform}
(*******************************************************************************
* 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; { we have not implemented it yet .. }
end; {ctm.inverse}
(******************************************************************************
* end. *
******************************************************************************)
end.