home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / 3 / 3d120.zip / CTM3D.PAS < prev    next >
Pascal/Delphi Source File  |  1992-08-08  |  32KB  |  763 lines

  1. (******************************************************************************
  2. *                                    Ctm3d                                    *
  3. ******************************************************************************)
  4. Unit Ctm3d;
  5.  
  6. (*******************************************************************************
  7. *                          Homogeneous Coordinates                            *
  8. *                          -----------------------                            *
  9. *                                                                             *
  10. *      Homogeneous coordinates allow transformations to be represented by     *
  11. *      matrices. A 3x3 matrix is used for 2D transformations, and a 4x4 matrix*
  12. *      for 3D transformations.                                                *
  13. *                                                                             *
  14. *      THIS MODULE IMPLEMENTS ONLY 3D TRANSFORMATIONS.                        *
  15. *                                                                             *
  16. *      in homogeneous coordination the point P(x,y,z) is represented as       *
  17. *      P(w*x, w*y, w*z, w) for any scale factor w!=0.                         *
  18. *      in this module w == 1.                                                 *
  19. *                                                                             *
  20. * Transformations:                                                            *
  21. *          1. translation                                                     *
  22. *                  [x, y, z] --> [x + Dx, y + Dy, z + Dz]                     *
  23. *                                                                             *
  24. *                              ┌          ┐                                   *
  25. *                              │1  0  0  0│                                   *
  26. *              T(Dx, Dy, Dz) = │0  1  0  0│                                   *
  27. *                              │0  0  1  0│                                   *
  28. *                              │Dx Dy Dz 1│                                   *
  29. *                              └          ┘                                   *
  30. *          2. scaling                                                         *
  31. *                  [x, y, z] --> [Sx * x, Sy * y, Sz * z]                     *
  32. *                                                                             *
  33. *                          ┌          ┐                                       *
  34. *                          │Sx 0  0  0│                                       *
  35. *              S(Sx, Sy) = │0  Sy 0  0│                                       *
  36. *                          │0  0  Sz 0│                                       *
  37. *                          │0  0  0  1│                                       *
  38. *                          └          ┘                                       *
  39. *                                                                             *
  40. *          3. rotation                                                        *
  41. *                                                                             *
  42. *              a) Around the Z axis:                                          *
  43. *                                                                             *
  44. *                  [x, y, z] --> [x*cost - t*sint, x*sint + y*cost, z]        *
  45. *                      ┌                  ┐                                   *
  46. *                      │cost  sint   0   0│                                   *
  47. *              Rz(t) = │-sint cost   0   0│                                   *
  48. *                      │0     0      1   0│                                   *
  49. *                      │0     0      0   1│                                   *
  50. *                      └                  ┘                                   *
  51. *                                                                             *
  52. *              b) Around the X axis:                                          *
  53. *                                                                             *
  54. *                  [x, y, z] --> [x, y*cost - z*sint, y*sint + z*cost]        *
  55. *                      ┌                  ┐                                   *
  56. *                      │1     0     0    0│                                   *
  57. *              Rx(t) = │0     cost  sint 0│                                   *
  58. *                      │0    -sint  cost 0│                                   *
  59. *                      │0     0     0    1│                                   *
  60. *                      └                  ┘                                   *
  61. *                                                                             *
  62. *              c) Around the Y axis:                                          *
  63. *                                                                             *
  64. *                  [x, y, z] --> [xcost + z*sint, y, z*cost - x*sint]         *
  65. *                      ┌                  ┐                                   *
  66. *                      │cost  0   -sint  0│                                   *
  67. *              Ry(t) = │0     1    0     0│                                   *
  68. *                      │sint  0    cost  0│                                   *
  69. *                      │0     0    0     1│                                   *
  70. *                      └                  ┘                                   *
  71. *                                                                             *
  72. *   transformation of the vector [x,y,z,1] by transformation matrix T is given *
  73. *   by the formula:                                                           *
  74. *                                         ┌   ┐                               *
  75. *              [x', y', z', 1] = [x,y,z,1]│ T │                               *
  76. *                                         └   ┘                               *
  77. * Optimizations:                                                              *
  78. *   The most general composition of R, S and T operations will produce a matrix*
  79. *   of the form:                                                              *
  80. *              ┌                       ┐                                      *
  81. *              │r11    r12     r13    0│                                      *
  82. *              │r21    r22     r23    0│                                      *
  83. *              │r31    r32     r33    0│                                      *
  84. *              │tx     ty      tz     1│                                      *
  85. *              └                       ┘                                      *
  86. *   The task of matrix multiplication can be simplified by                    *
  87. *      x' = x*r11 + y*r21 + z*r31 + tx                                        *
  88. *      y' = x*r12 + y*r22 + z*r32 + ty                                        *
  89. *      z' = x*r13 + y*r23 + z*r33 + tz                                        *
  90. *                                                                             *
  91. *                                                                             *
  92. * See also:                                                                   *
  93. *      "Fundamentals of Interactive Computer Graphics" J.D FOLEY A.VAN DAM    *
  94. *      Adison-Weslely ISBN 0-201-14468-9 pp 245-265                           *
  95. *******************************************************************************)
  96.  
  97. interface
  98.  
  99. uses hdr3d;
  100.  
  101. type
  102.        ctmPtr = ^ctm;
  103.     ctm = object
  104.        r11, r12, r13   : real;
  105.        r21, r22, r23   : real;
  106.        r31, r32, r33   : real;
  107.        tx,  ty,  tz    : real;
  108.  
  109.        constructor SetUnit;
  110.        constructor Copy(var src : ctm);
  111.        procedure save(var dest : ctm);
  112.  
  113.        procedure translate(Dx, Dy, Dz : real);
  114.  
  115.        procedure translateX(dx : real);
  116.        procedure translateY(dy : real);
  117.        procedure translateZ(dz : real);
  118.        {use these routines for single axis translations, they are faster!}
  119.  
  120.        procedure rotateX(t : real);
  121.        procedure rotateY(t : real);
  122.        procedure rotateZ(t : real);
  123.  
  124.        procedure scale(Sx, Sy, Sz : real);
  125.  
  126.        procedure scaleX(sx : real);
  127.        procedure scaleY(sy : real);
  128.        procedure scaleZ(sz : real);
  129.        {use these routines for single axis scaling, they are faster!!!}
  130.  
  131.        procedure Left_translate(Dx, Dy, Dz : real);
  132.  
  133.        procedure Left_translateX(dx : real);
  134.        procedure Left_translateY(dy : real);
  135.        procedure Left_translateZ(dz : real);
  136.        {use theseLeft_ routines for single axis translations, they are faster!}
  137.  
  138.        procedure Left_rotateX(t : real);
  139.        procedure Left_rotateY(t : real);
  140.        procedure Left_rotateZ(t : real);
  141.  
  142.        procedure Left_scale(Sx, Sy, Sz : real);
  143.  
  144.        procedure Left_scaleX(sx : real);
  145.        procedure Left_scaleY(sy : real);
  146.        procedure Left_scaleZ(sz : real);
  147.        {use these routines for single axis scaling, they are faster!!!}
  148.  
  149.        procedure transform(var t: point3d; p : point3d);
  150.        {
  151.          Note that t (target) is var, but p is NOT.
  152.          p cannot be a var parameter, because if the same point is
  153.          transformed, data should be copied for correct results
  154.        }
  155.        procedure inv_transform(var p : point3d);
  156.        { inv_transform changes the input point }
  157.  
  158.        procedure inverse; { M ^-1 }
  159.        procedure multiply(var c : ctm); {multiply from right self * c}
  160.        procedure Multiply_2(var a, b : ctm);
  161.     end;
  162.  
  163. implementation
  164.  
  165. (*---------------------------------------------------------------------------
  166.  * ctm.SetUnit -- set the ctm to the unit matrix.
  167.  *---------------------------------------------------------------------------
  168.  *)
  169. constructor ctm.SetUnit;
  170. begin
  171.     r11 := 1; r12 := 0; r13 := 0;
  172.     r21 := 0; r22 := 1; r23 := 0;
  173.     r31 := 0; r32 := 0; r33 := 1;
  174.     Tx := 0; Ty := 0; Tz := 0;
  175. end;
  176.  
  177. (*---------------------------------------------------------------------------
  178.  * ctm.Copy  -- Copy another ctm to self.
  179.  *---------------------------------------------------------------------------
  180.  *)
  181. constructor ctm.copy;
  182. begin
  183.     { This copy is done this way instead of
  184.        Self := Src;  becuase TP does not do that as expected. }
  185.  
  186.     r11 := Src.r11;
  187.     r12 := Src.r12;
  188.     r13 := Src.r13;
  189.     r21 := Src.r21;
  190.     r22 := Src.r22;
  191.     r23 := Src.r23;
  192.     r31 := Src.r31;
  193.     r32 := Src.r32;
  194.     r33 := Src.r33;
  195.     tx := Src.tx;
  196.     ty := Src.ty;
  197.     tz := Src.tz;
  198. end;
  199.  
  200. (* ctm.save save ctm in a specified variable ctm *)
  201. (*******************************************************************************
  202. *                                  ctm.save                                   *
  203. *******************************************************************************)
  204. procedure ctm.save;
  205. begin
  206.     dest := self;
  207. end;
  208.  
  209. (*---------------------------------------------------------------------------
  210.  * ctm.translate -- multyply ctm by T(dx,dy,dz). ctm = ctm * T(dx,dy,dz)
  211.  *     ┌                      ┐    ┌             ┐    ┌                   ┐
  212.  *     │r11    r12     r13    0│    │1  0   0   0│    │r11   r12   r31   0│
  213.  *     │r21    r22     r23    0│ *  │0  1   0   0│ =  │r21   r22   r31   0│
  214.  *     │r31    r32     r33    0│    │0  0   1   0│    │r21   r22   r31   0│
  215.  *     │tx     ty      tz     1│    │Dx  Dy  Dz  1│    │tx'   ty'   tz'   1│
  216.  *     └                      ┘    └             ┘    └                   ┘
  217.  *
  218.  *    tx' = tx + Dx
  219.  *    ty' = ty + Dy
  220.  *    tz' = tz + Dz
  221.  *---------------------------------------------------------------------------
  222.  *)
  223. procedure ctm.translate;
  224. begin
  225.     Tx := Tx + Dx;
  226.     Ty := Ty + Dy;
  227.     Tz := Tz + Dz;
  228. end;
  229.  
  230.  
  231. (*---------------------------------------------------------------------------
  232.  * ctm.Left_translate  --  multyply ctm by T(dx,dy,dz) on the left.
  233.  *                         ctm = T(dx,dy,dz) * ctm
  234.  *      ┌             ┐ ┌                       ┐     ┌                   ┐
  235.  *      │1   0   0   0│ │r11    r12     r13    0│     │r11   r12   r31   0│
  236.  *      │0   1   0   0│ │r21    r22     r23    0│  =  │r21   r22   r31   0│
  237.  *      │0   0   1   0│ │r31    r32     r33    0│     │r21   r22   r31   0│
  238.  *      │Dx  Dy  Dz  1│ │tx     ty      tz     1│     │tx'   ty'   tz'   1│
  239.  *      └             ┘ └                       ┘     └                   ┘
  240.  *
  241.  *    tx' = r11 * Dx + r21 * Dy + r31 * Dz + tx
  242.  *    ty' = r12 * Dx + r22 * Dy + r32 * Dz + ty
  243.  *    tz' = r13 * Dx + r23 * Dy + r33 * Dz + tz
  244.  *---------------------------------------------------------------------------
  245.  *)
  246. procedure ctm.Left_translate;
  247. begin
  248.     Tx := Tx + r11 * Dx + r21 * Dy + r31 * Dz;
  249.     Ty := Ty + r12 * Dx + r22 * Dy + r32 * Dz;
  250.     Tz := Tz + r13 * Dx + r23 * Dy + r33 * Dz;
  251. end;
  252.  
  253.  
  254. (*******************************************************************************
  255. *                               ctm.translateX                                *
  256. *******************************************************************************)
  257. procedure ctm.translateX;
  258. begin
  259.        tx := tx+dx;
  260. end;
  261.  
  262. (*******************************************************************************
  263. *                            ctm.Left_translateX                              *
  264. *******************************************************************************)
  265. procedure ctm.Left_translateX;
  266. begin
  267.     tx := tx + dx * r11;
  268.     ty := ty + dx * r12;
  269.     tz := tz + dx * r13;
  270. end;
  271.  
  272. (*******************************************************************************
  273. *                               ctm.translateY                                *
  274. *******************************************************************************)
  275. procedure ctm.translateY;
  276. begin
  277.     ty := ty+dy;
  278. end;
  279.  
  280. (*******************************************************************************
  281. *                            ctm.Left_translateY                              *
  282. *******************************************************************************)
  283. procedure ctm.Left_translateY;
  284. begin
  285.        tx := tx + dy * r21;
  286.        ty := ty + dy * r22;
  287.        tz := tz + dy * r23;
  288. end;
  289.  
  290.  
  291. (*******************************************************************************
  292. *                               ctm.translateZ                                *
  293. *******************************************************************************)
  294. procedure ctm.translateZ;
  295. begin
  296.        tz := tz+dz;
  297. end;
  298.  
  299. (*******************************************************************************
  300. *                            ctm.Left_translateZ                              *
  301. *******************************************************************************)
  302. procedure ctm.Left_translateZ;
  303. begin
  304.        tx := tx + dz * r31;
  305.        ty := ty + dz * r32;
  306.        tz := tz + dz * r33;
  307. end;
  308.  
  309.  
  310. {the above 6 procedures are used for single axis translation - # of FP
  311.        operations is 1/3, # of arguments passed is 1/3, try using these
  312.        procedures when possiable to improve animation}
  313.  
  314. (*---------------------------------------------------------------------------
  315.  * ctm.scale -- multyply ctm by S(sx,sy,sz). ctm = ctm * S(sx,sy,sz)
  316.  *   ┌                   ┐   ┌             ┐   ┌                            ┐
  317.  *   │r11   r12    r13  0│   │Sx  0   0   0│   │Sx*r11   Sy*r12   Sz*r13   0│
  318.  *   │r21   r22    r23  0│ * │0   Sy  0   0│ = │Sx*r21   Sy*r22   Sz*r13   0│
  319.  *   │r31   r32    r33  0│   │0   0   Sz  0│   │Sx*r31   Sy*r32   Sz*r33   0│
  320.  *   │tx    ty    tz    1│   │0   0   0   1│   │Sx*tx    Sy*ty    Sz*tz    1│
  321.  *   └                   ┘   └             ┘   └                            ┘
  322.  *---------------------------------------------------------------------------
  323.  *)
  324. procedure ctm.scale;
  325. begin
  326.     r11 := r11*Sx;     r12 := r12*Sy;      r13 := r13*Sz;
  327.     r21 := r21*Sx;     r22 := r22*Sy;      r23 := r23*Sz;
  328.     r31 := r31*Sx;     r32 := r32*Sy;      r33 := r33*Sz;
  329.     tx :=  tx*Sx;      ty  :=  ty*Sy;      tz  :=  tz*Sz
  330. end;
  331.  
  332.  
  333. (*---------------------------------------------------------------------------
  334.  * ctm.Left_scale   -- multyply ctm by S(sx,sy,sz) on the left.
  335.  *                     ctm = S(sx,sy,sz) * ctm
  336.  *   ┌            ┐   ┌                    ┐   ┌                            ┐
  337.  *   │Sx  0   0   0│   │r11   r12    r13   0│  │Sx*r11   Sy*r12   Sz*r13   0│
  338.  *   │0   Sy  0   0│ * │r21   r22    r23   0│ = │Sx*r21   Sy*r22   Sz*r13   0│
  339.  *   │0   0   Sz  0│   │r31   r32    r33   0│  │Sx*r31   Sy*r32   Sz*r33   0│
  340.  *   │0   0   0   1│   │tx    ty     tz    1│  │   tx       ty       tz    1│
  341.  *   └            ┘   └                    ┘   └                            ┘
  342.  *---------------------------------------------------------------------------
  343.  *)
  344. procedure ctm.Left_scale;
  345. begin
  346.     r11 := r11*Sx;     r12 := r12*Sy;      r13 := r13*Sz;
  347.     r21 := r21*Sx;     r22 := r22*Sy;      r23 := r23*Sz;
  348.     r31 := r31*Sx;     r32 := r32*Sy;      r33 := r33*Sz;
  349. end;
  350.  
  351.  
  352. (*******************************************************************************
  353. *                                 ctm.scaleZ                                  *
  354. *******************************************************************************)
  355. procedure ctm.scaleZ;
  356. begin
  357.     r13 := r13*Sz;
  358.     r23 := r23*Sz;
  359.     r33 := r33*Sz;
  360.     tz :=  tz*Sz;
  361. end;
  362.  
  363. (*******************************************************************************
  364. *                              ctm.Left_scaleZ                                *
  365. *******************************************************************************)
  366. procedure ctm.Left_scaleZ;
  367. begin
  368.     r31 := r31*Sz;
  369.     r32 := r32*Sz;
  370.     r33 := r33*Sz;
  371. end;
  372.  
  373.  
  374. (*******************************************************************************
  375. *                                 ctm.scaleY                                  *
  376. *******************************************************************************)
  377. procedure ctm.scaleY;
  378. begin
  379.        r12 := r12*Sy;
  380.        r22 := r22*Sy;
  381.        r32 := r32*Sy;
  382.        ty  :=  ty*Sy;
  383. end;
  384.  
  385. (*******************************************************************************
  386. *                              ctm.Left_scaleY                                *
  387. *******************************************************************************)
  388. procedure ctm.Left_scaleY;
  389. begin
  390.     r21 := r21*Sy;
  391.     r22 := r22*Sy;
  392.     r23 := r23*Sy;
  393. end;
  394.  
  395. (*******************************************************************************
  396. *                                 ctm.scaleX                                  *
  397. *******************************************************************************)
  398. procedure ctm.scaleX;
  399. begin
  400.     r11 := r11*Sx;
  401.     r21 := r21*Sx;
  402.     r31 := r31*Sx;
  403.     tx :=  tx*Sx;
  404. end;
  405.  
  406. (*******************************************************************************
  407. *                              ctm.Left_scaleX                                *
  408. *******************************************************************************)
  409. procedure ctm.Left_scaleX;
  410. begin
  411.     r11 := r11*Sx;
  412.     r12 := r12*Sx;
  413.     r13 := r13*Sx;
  414. end;
  415.  
  416.  
  417. {the above 6 routines should be used for single axis scale, they are much
  418.        faster then calling the general scale routine (with a factor of
  419.        better then 3), and require less arguments}
  420.  
  421.  
  422. (*---------------------------------------------------------------------------
  423.  * ctm.rotateZ -- multyply ctm by Rz(t). ctm = ctm * Rz(t)
  424.  *   ┌                   ┐   ┌                  ┐   ┌                    ┐
  425.  *   │r11   r12    r13  0│   │cost  sint   0   0│   │r11'  r12'   r13   0│
  426.  *   │r21   r22    r23  0│   │-sint cost   0   0│   │r21'  r22'   r23   0│
  427.  *   │r31   r32    r33  0│ * │0     0      1   0│ = │r31'  r32'   r33   0│
  428.  *   │tx    ty    tz    1│   │0     0      0   1│   │tx'   ty'    tz    1│
  429.  *   └                   ┘   └                  ┘   └                    ┘
  430.  *
  431.  *   r11' = r11*cost - r12*sint
  432.  *   r21' = r21*cost - r22*sint
  433.  *   r31' = r31*cost - r32*sint
  434.  *   tx'  = tx *cost - ty *sint
  435.  *   r12' = r11*sint + r12*cost
  436.  *   r22' = r21*sint + r22*cost
  437.  *   r32' = r31*sint + r32*cost
  438.  *   ty'  = tx *sint + ty *cost
  439.  *
  440.  *---------------------------------------------------------------------------
  441.  *)
  442. procedure ctm.rotateZ;
  443. var
  444.     cost, sint : real;
  445.     tmp        : real;
  446. begin
  447.     cost := cos(t / 180.0 * 3.1415926535897932385);
  448.     sint := sin(t / 180.0 * 3.1415926535897932385);
  449.  
  450.     tmp := r11*cost - r12*sint;
  451.     r12 := r11*sint + r12*cost;
  452.     r11 := tmp;
  453.     tmp := r21*cost - r22*sint;
  454.     r22 := r21*sint + r22*cost;
  455.     r21 := tmp;
  456.     tmp := r31*cost - r32*sint;
  457.     r32 := r31*sint + r32*cost;
  458.     r31 := tmp;
  459.     tmp := tx *cost - ty *sint;
  460.     ty := tx *sint + ty *cost;
  461.     tx := tmp;
  462. end;
  463.  
  464. (*---------------------------------------------------------------------------
  465.  * ctm.Left_rotateZ  -- multyply ctm by Rz(t) on the left. ctm = Rz(t) * ctm
  466.  *  ┌                 ┐   ┌                    ┐   ┌                    ┐
  467.  *  │cost  sint   0   0│   │r11   r12   r13   0│   │r11'  r12'   r13'  0│
  468.  *  │-sint cost   0   0│   │r21   r22   r23   0│   │r21'  r22'   r23'  0│
  469.  *  │0    0      1   0│ * │r31   r32    r33   0│ = │r31   r32    r33   0│
  470.  *  │0    0      0   1│   │tx    ty     tz    1│   │tx    ty     tz    1│
  471.  *  └                 ┘   └                    ┘   └                    ┘
  472.  *
  473.  *   r11' = r11*cost + r21*sint
  474.  *   r12' = r12*cost + r22*sint
  475.  *   r13' = r13*cost + r23*sint
  476.  *   r21' = r21*cost - r11*sint
  477.  *   r22' = r22*cost - r12*sint
  478.  *   r23' = r23*cost - r13*sint
  479.  *
  480.  *---------------------------------------------------------------------------
  481.  *)
  482. procedure ctm.Left_rotateZ;
  483. var
  484.     cost, sint : real;
  485.     tmp        : real;
  486. begin
  487.      cost := cos(t / 180.0 * 3.1415926535897932385);
  488.      sint := sin(t / 180.0 * 3.1415926535897932385);
  489.  
  490.     tmp := r11 * cost + r21 * sint;
  491.     r21 := r21 * cost - r11 * sint;
  492.     r11 := tmp;
  493.     tmp := r12 * cost + r22 * sint;
  494.     r22 := r22 * cost - r12 * sint;
  495.     r12 := tmp;
  496.     tmp := r13 * cost + r23 * sint;
  497.     r23 := r23 * cost - r13 * sint;
  498.     r13 := tmp;
  499. end;
  500.  
  501. (*---------------------------------------------------------------------------
  502.  * ctm.rotateX -- multyply ctm by Rx(t). ctm = ctm * Rx(t)
  503.  *   ┌                   ┐   ┌                  ┐   ┌                    ┐
  504.  *   │r11   r12    r13  0│   │1     0     0    0│   │r11   r12'   r13'  0│
  505.  *   │r21   r22    r23  0│   │0     cost  sint 0│   │r21   r22'   r23'  0│
  506.  *   │r31   r32    r33  0│ * │0    -sint  cost 0│ = │r31   r32'   r33'  0│
  507.  *   │tx    ty    tz    1│   │0     0     0    1│   │tx    ty'    tz'   1│
  508.  *   └                   ┘   └                  ┘   └                    ┘
  509.  *
  510.  *   r12' = r12*cost - r13*sint
  511.  *   r13' = r12*sint + r13*cost
  512.  *   r22' = r22*cost - r23*sint
  513.  *   r23' = r22*sint + r23*cost
  514.  *   ty'  = ty *cost - tz *sint
  515.  *   tz'  = ty *sint + tz *cost
  516.  *---------------------------------------------------------------------------
  517.  *)
  518. procedure ctm.rotateX;
  519. var
  520.     cost, sint : real;
  521.     tmp        : real;
  522. begin
  523.      cost := cos(t / 180.0 * 3.1415926535897932385); {constants are evaluated at compile time}
  524.      sint := sin(t / 180.0 * 3.1415926535897932385);
  525.  
  526.     tmp := r12*cost - r13*sint;
  527.     r13 := r12*sint + r13*cost;
  528.     r12 := tmp;
  529.     tmp := r22*cost - r23*sint;
  530.     r23 := r22*sint + r23*cost;
  531.     r22 := tmp;
  532.     tmp := r32*cost - r33*sint;
  533.     r33 := r32*sint + r33*cost;
  534.     r32 := tmp;
  535.     tmp := ty *cost - tz *sint;
  536.     tz := ty *sint + tz *cost;
  537.     ty := tmp;
  538. end;
  539.  
  540.  
  541. (*---------------------------------------------------------------------------
  542.  * ctm.Left_rotateX  -- multyply ctm by Rx(t) on the left. ctm = Rx(t) * ctm
  543.  *  ┌                 ┐   ┌                    ┐   ┌                    ┐
  544.  *  │1    0     0    0│   │r11   r12    r13   0│   │r11   r12    r13   0│
  545.  *  │0    cost  sint 0│   │r21   r22    r23   0│   │r21'  r22'   r23'  0│
  546.  *  │0   -sint  cost 0│ * │r31   r32    r33   0│ = │r31'  r32'   r33'  0│
  547.  *  │0    0     0    1│   │tx    ty     tz    1│   │tx    ty     tz    1│
  548.  *  └                 ┘   └                    ┘   └                    ┘
  549.  *
  550.  *   r21' = r21*cost + r31*sint
  551.  *   r22' = r22*cost + r32*sint
  552.  *   r23' = r23*cost + r33*sint
  553.  *   r31' = r31*cost - r21*sint
  554.  *   r32' = r32*cost - r22*sint
  555.  *   r33' = r33*cost - r23*sint
  556.  *
  557.  *---------------------------------------------------------------------------
  558.  *)
  559. procedure ctm.Left_rotateX;
  560. var
  561.     cost, sint : real;
  562.     tmp        : real;
  563. begin
  564.      cost := cos(t / 180.0 * 3.1415926535897932385);
  565.      sint := sin(t / 180.0 * 3.1415926535897932385);
  566.  
  567.     tmp := r21 * cost + r31 * sint;
  568.     r31 := r31 * cost - r21 * sint;
  569.     r21 := tmp;
  570.     tmp := r22 * cost + r32 * sint;
  571.     r32 := r32 * cost - r22 * sint;
  572.     r22 := tmp;
  573.     tmp := r23 * cost + r33 * sint;
  574.     r33 := r33 * cost - r23 * sint;
  575.     r23 := tmp;
  576. end;
  577.  
  578. (*---------------------------------------------------------------------------
  579.  * ctm.rotateY -- multyply ctm by Rx(t). ctm = ctm * Ry(t)
  580.  *   ┌                   ┐   ┌                  ┐   ┌                    ┐
  581.  *   │r11   r12    r13  0│   │cost  0   -sint  0│   │r11'  r12    r13'  0│
  582.  *   │r21   r22    r23  0│   │0     1    0     0│   │r21'  r22    r23'  0│
  583.  *   │r31   r32    r33  0│ * │sint  0    cost  0│ = │r31'  r32    r33'  0│
  584.  *   │tx    ty    tz    1│   │0     0    0     1│   │tx    ty'    tz'   1│
  585.  *   └                   ┘   └                  ┘   └                    ┘
  586.  *
  587.  *   r11' = r11*cost + r13*sint
  588.  *   r13' = r13*cost - r11*sint
  589.  *   r21' = r21*cost + r23*sint
  590.  *   r23' = r23*cost - r21*sint
  591.  *   tx'  = tx *cost + tz *sint
  592.  *   tz'  = tz *cost - tx *sint
  593.  *---------------------------------------------------------------------------
  594.  *)
  595. procedure ctm.rotateY;
  596. var
  597.     cost, sint : real;
  598.     tmp        : real;
  599. begin
  600.      cost := cos(t / 180.0 * 3.1415926535897932385);
  601.      sint := sin(t / 180.0 * 3.1415926535897932385);
  602.  
  603.     tmp := r11*cost + r13*sint;
  604.     r13 := r13*cost - r11*sint;
  605.     r11 := tmp;
  606.     tmp := r21*cost + r23*sint;
  607.     r23 := r23*cost - r21*sint;
  608.     r21 := tmp;
  609.     tmp := r31*cost + r33*sint;
  610.     r33 := r33*cost - r31*sint;
  611.     r31 := tmp;
  612.     tmp := tx *cost + tz *sint;
  613.     tz := tz *cost - tx *sint;
  614.     tx := tmp;
  615. end;
  616.  
  617. (*---------------------------------------------------------------------------
  618.  * ctm.Left_rotateY  -- multyply ctm by Ry(t) on the left. ctm = Ry(t) * ctm
  619.  *  ┌                 ┐   ┌                    ┐   ┌                    ┐
  620.  *  │cost  0   -sint  0│   │r11   r12   r13   0│   │r11'  r12'   r13'  0│
  621.  *  │0    1    0     0│   │r21   r22    r23   0│   │r21   r22    r23   0│
  622.  *  │sint  0   cost  0│ * │r31   r32    r33   0│ = │r31'  r32'   r33'  0│
  623.  *  │0    0    0     1│   │tx    ty     tz    1│   │tx    ty     tz    1│
  624.  *  └                 ┘   └                    ┘   └                    ┘
  625.  *
  626.  *   r11' = r11*cost - r31*sint
  627.  *   r12' = r11*cost - r32*sint
  628.  *   r13' = r11*cost - r33*sint
  629.  *   r31' = r31*cost + r11*sint
  630.  *   r32' = r32*cost + r12*sint
  631.  *   r33' = r33*cost + r13*sint
  632.  *
  633.  *---------------------------------------------------------------------------
  634.  *)
  635. procedure ctm.Left_rotateY;
  636. var
  637.     cost, sint : real;
  638.     tmp        : real;
  639. begin
  640.      cost := cos(t / 180.0 * 3.1415926535897932385);
  641.      sint := sin(t / 180.0 * 3.1415926535897932385);
  642.  
  643.     tmp := r11 * cost - r31 * sint;
  644.     r31 := r31 * cost + r11 * sint;
  645.     r11 := tmp;
  646.     tmp := r11 * cost - r32 * sint;
  647.     r32 := r32 * cost + r12 * sint;
  648.     r12 := tmp;
  649.     tmp := r11 * cost - r33 * sint;
  650.     r33 := r33 * cost + r13 * sint;
  651.     r13 := tmp;
  652. end;
  653.  
  654. (*---------------------------------------------------------------------------
  655.  *  ctm.transform   -- transform [x,y,z] by the CTM.
  656.  *
  657.  *  See remarks at the top.
  658.  *---------------------------------------------------------------------------
  659.  *)
  660. procedure ctm.transform;
  661. begin
  662.     t.x := p.x*r11 + p.y*r21 + p.z*r31 + tx;
  663.     t.y := p.x*r12 + p.y*r22 + p.z*r32 + ty;
  664.     t.z := p.x*r13 + p.y*r23 + p.z*r33 + tz;
  665. end;
  666.  
  667. (*---------------------------------------------------------------------------
  668.  *  ctm.inv_transform -- transform [x',y',z'] by the INVERS
  669.  *                      transfomation CTM^-1
  670.  *
  671.  *  The inverse transformation is calculated by solving the 3 equations
  672.  *     for x,y,z.
  673.  *
  674.  *      x' = x*r11 + y*r21 + z*r31 + tx
  675.  *      y' = x*r12 + y*r22 + z*r32 + ty
  676.  *      z' = x*r13 + y*r23 + z*r33 + tz
  677.  *
  678.  *---------------------------------------------------------------------------
  679.  *)
  680. procedure ctm.inv_transform;
  681. var
  682.     d      : real;     { Delta }
  683.     d_x     : real;    { Delta X [X = Delta X / Delta] }
  684.     d_y     : real;    { Delta Y [Y = Delta Y / Delta] }
  685.     d_z     : real;    { Delta Z [Z = Delta Z / Delta] }
  686. begin
  687.     d :=  r11*(r22*r33 - r32*r23)
  688.         -r21*(r12*r33 - r13*r32)
  689.         +r31*(r12*r23 - r22*r13);
  690.     d_x:=  (p.x - tx)*(r22*r33 - r32*r23)
  691.          -r21*((p.y - ty)*r33 - (p.z - tz)*r32)
  692.          +r31*((p.y - ty)*r23 - r22*(p.z - tz));
  693.     d_y:=  r11*((p.y - ty)*r33 - r32*(p.z - tz))
  694.          -(p.x - tx)*(r12*r33 - r13*r32)
  695.          +r31*(r12*(p.z - tz) - (p.y - ty)*r13);
  696.     d_z:=  r11*(r22*(p.z - tz) - (p.y - ty)*r23)
  697.          -r21*(r12*(p.z - tz) - r13*(p.y - ty))
  698.          +(p.x - tx)*(r12*r23 - r22*r13);
  699.     p.x := round(d_x / d);
  700.     p.y := round(d_y / d);
  701.     p.z := round(d_z / d);
  702. end;
  703.  
  704. (*******************************************************************************
  705. *                                ctm.multiply                                 *
  706. * here we multiply our ctm with another from the right : self * c -> self      *
  707. *******************************************************************************)
  708. procedure ctm.multiply;
  709. var
  710.     t : ctm;
  711. begin
  712.        t.r11 := r11*c.r11+r12*c.r21+r13*c.r31;
  713.        t.r21 := r21*c.r11+r22*c.r21+r23*c.r31;
  714.        t.r31 := r31*c.r11+r32*c.r21+r33*c.r31;
  715.        t.tx  := tx *c.r11+ty *c.r21+tz *c.r31+c.tx;
  716.  
  717.        t.r12 := r11*c.r12+r12*c.r22+r13*c.r32;
  718.        t.r22 := r21*c.r12+r22*c.r22+r23*c.r32;
  719.        t.r32 := r31*c.r12+r32*c.r22+r33*c.r32;
  720.        t.ty  := tx *c.r12+ty *c.r22+tz *c.r32+c.ty;
  721.  
  722.        t.r13 := r11*c.r13+r12*c.r23+r13*c.r33;
  723.        t.r23 := r21*c.r13+r22*c.r23+r23*c.r33;
  724.        t.r33 := r31*c.r13+r32*c.r23+r33*c.r33;
  725.        t.tz  := tx *c.r13+ty *c.r23+tz *c.r33+c.tz;
  726.  
  727.        copy(t);
  728. end; {ctm.multiply}
  729.  
  730. (*******************************************************************************
  731. *                                ctm.multiply_2                               *
  732. * here we multiply our ctm with another from the right : self * c -> self      *
  733. *******************************************************************************)
  734. procedure ctm.multiply_2;
  735. begin
  736.     r11 := a.r11*b.r11+a.r12*b.r21+a.r13*b.r31;
  737.     r21 := a.r21*b.r11+a.r22*b.r21+a.r23*b.r31;
  738.     r31 := a.r31*b.r11+a.r32*b.r21+a.r33*b.r31;
  739.     tx := a.tx *b.r11+a.ty *b.r21+a.tz *b.r31+b.tx;
  740.  
  741.     r12 := a.r11*b.r12+a.r12*b.r22+a.r13*b.r32;
  742.     r22 := a.r21*b.r12+a.r22*b.r22+a.r23*b.r32;
  743.     r32 := a.r31*b.r12+a.r32*b.r22+a.r33*b.r32;
  744.     ty := a.tx *b.r12+a.ty *b.r22+a.tz *b.r32+b.ty;
  745.  
  746.     r13 := a.r11*b.r13+a.r12*b.r23+a.r13*b.r33;
  747.     r23 := a.r21*b.r13+a.r22*b.r23+a.r23*b.r33;
  748.     r33 := a.r31*b.r13+a.r32*b.r23+a.r33*b.r33;
  749.     tz := a.tx *b.r13+a.ty *b.r23+a.tz *b.r33+b.tz;
  750. end; {ctm.multiply_2}
  751.  
  752.  
  753. (*******************************************************************************
  754. *                                ctm.inverse                                  *
  755. *******************************************************************************)
  756. procedure ctm.inverse;
  757. begin
  758.      runerror;
  759. end;
  760.  
  761.  
  762. end.
  763.