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