Update copyright date; remove old CVS keyword
[ctsim.git] / libctgraphics / transformmatrix.cpp
1 /*****************************************************************************
2 ** FILE IDENTIFICATION
3 **
4 **      Name:       transformmatrix.cpp
5 **      Function:   Transform Matrix routine for graphic library
6 **      Programmer: Kevin Rosenberg
7 **      Date Started:   1-22-85
8 **
9 **  This is part of the CTSim program
10 **  Copyright (c) 1983-2009 Kevin Rosenberg
11 **
12 **  This program is free software; you can redistribute it and/or modify
13 **  it under the terms of the GNU General Public License (version 2) as
14 **  published by the Free Software Foundation.
15 **
16 **  This program is distributed in the hope that it will be useful,
17 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 **  GNU General Public License for more details.
20 **
21 **  You should have received a copy of the GNU General Public License
22 **  along with this program; if not, write to the Free Software
23 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24 ******************************************************************************/
25
26 #include <iostream>
27 #include "ctsupport.h"
28 #include "transformmatrix.h"
29
30
31 TransformationMatrix2D::TransformationMatrix2D (double m[3][3])
32 {
33   mtx[0][0] = m[0][0]; mtx[0][1] = m[0][1]; mtx[0][2] = m[0][2];
34   mtx[1][0] = m[1][0]; mtx[1][1] = m[1][1]; mtx[1][2] = m[1][2];
35   mtx[2][0] = m[2][0]; mtx[2][1] = m[2][1]; mtx[2][2] = m[2][2];
36 }
37
38 void
39 TransformationMatrix2D::setTranslate (double x, double y)
40 {
41   setIdentity();
42   mtx[2][0] = x;
43   mtx[2][1] = y;
44 }
45
46
47 void
48 TransformationMatrix2D::setScale (double sx, double sy)
49 {
50   setIdentity();
51   mtx[0][0] = sx;
52   mtx[1][1] = sy;
53 }
54
55
56 void
57 TransformationMatrix2D::setShear (double shrx, double shry)
58 {
59   setIdentity();
60   mtx[1][0] = shrx;
61   mtx[0][1] = shry;
62 }
63
64 void
65 TransformationMatrix2D::setRotate (double theta)
66 {
67     double s = sin (theta);
68     double c = cos (theta);
69
70     setIdentity();
71
72     mtx[0][0] =  c;  mtx[0][1] = s;
73     mtx[1][0] = -s;  mtx[1][1] = c;
74 }
75
76
77 void
78 TransformationMatrix2D::setIdentity ()
79 {
80     mtx[0][0] = 1.;  mtx[0][1] = 0.;  mtx[0][2] = 0.;
81     mtx[1][0] = 0.;  mtx[1][1] = 1.;  mtx[1][2] = 0.;
82     mtx[2][0] = 0.;  mtx[2][1] = 0.;  mtx[2][2] = 1.;
83 }
84
85
86 const TransformationMatrix2D
87 TransformationMatrix2D::invert () const
88 {
89   double b[3][3];
90
91   double determ = determinant ();
92   if (fabs(determ) < 1E-6) {
93     sys_error (ERR_WARNING, "Determinant = %g [TransformationMatrix2D::invert]", determ);
94         print (std::cout);
95         std::cout << std::endl;
96   }
97
98   b[0][0] =  (mtx[1][1] * mtx[2][2] - mtx[2][1] * mtx[1][2]) / determ;
99   b[1][0] = -(mtx[1][0] * mtx[2][2] - mtx[2][0] * mtx[1][2]) / determ;
100   b[2][0] =  (mtx[1][0] * mtx[2][1] - mtx[2][0] * mtx[1][1]) / determ;
101
102   b[0][1] = -(mtx[0][1] * mtx[2][2] - mtx[2][1] * mtx[0][2]) / determ;
103   b[1][1] =  (mtx[0][0] * mtx[2][2] - mtx[2][0] * mtx[0][2]) / determ;
104   b[2][1] = -(mtx[0][0] * mtx[2][1] - mtx[2][0] * mtx[0][1]) / determ;
105
106   b[0][2] =  (mtx[0][1] * mtx[1][2] - mtx[1][1] * mtx[0][2]) / determ;
107   b[1][2] = -(mtx[0][0] * mtx[1][2] - mtx[1][0] * mtx[0][2]) / determ;
108   b[2][2] =  (mtx[0][0] * mtx[1][1] - mtx[1][0] * mtx[0][1]) / determ;
109
110   return TransformationMatrix2D (b);
111 }
112
113
114 double
115 TransformationMatrix2D::determinant () const
116 {
117   return
118     (mtx[0][0] * mtx[1][1] * mtx[2][2] - mtx[0][0] * mtx[2][1] * mtx[1][2] -
119      mtx[0][1] * mtx[1][0] * mtx[2][2] + mtx[0][1] * mtx[2][0] * mtx[1][2] +
120      mtx[0][2] * mtx[1][0] * mtx[2][1] - mtx[0][2] * mtx[2][0] * mtx[1][1]);
121 }
122
123
124 void
125 TransformationMatrix2D::transformPoint (double* pX, double *pY) const
126 {
127   double x = *pX * mtx[0][0] + *pY * mtx[1][0] + mtx[2][0];
128   double y = *pX * mtx[0][1] + *pY * mtx[1][1] + mtx[2][1];
129
130   *pX = x;
131   *pY = y;
132 }
133
134 void
135 TransformationMatrix2D::print (std::ostream& ostr) const
136 {
137         std::cout << mtx[0][0] << " " << mtx[0][1] << " " << mtx[0][2] << std::endl;
138         std::cout << mtx[1][0] << " " << mtx[1][1] << " " << mtx[1][2] << std::endl;
139         std::cout << mtx[2][0] << " " << mtx[2][1] << " " << mtx[2][2] << std::endl;
140 }
141
142
143 // Friend of TransformMatrix2D
144
145 const TransformationMatrix2D operator* (const TransformationMatrix2D& a, const TransformationMatrix2D& b)
146 {
147     double c[3][3];
148
149     for (int row = 0; row < 3; row++)
150       for (int col = 0; col < 3; col++) {
151         c[row][col] = 0.;
152         for (int calc = 0; calc < 3; calc++)
153           c[row][col] += a.mtx[row][calc] * b.mtx[calc][col];
154       }
155
156     return TransformationMatrix2D (c);
157 }