1 #ifndef __NR_MATRIX_H__
2 #define __NR_MATRIX_H__
4 /** \file
5 * Definition of NR::Matrix type.
6 *
7 * \note Operator functions (e.g. Matrix * Matrix etc.) are mostly in
8 * libnr/nr-matrix-ops.h. See end of file for discussion.
9 *
10 * Main authors:
11 * Lauris Kaplinski <lauris@kaplinski.com>:
12 * Original NRMatrix definition and related macros.
13 *
14 * Nathan Hurst <njh@mail.csse.monash.edu.au>:
15 * NR::Matrix class version of the above.
16 *
17 * This code is in public domain.
18 */
20 #include <glib.h> // g_assert()
21 #include <glib/gmessages.h>
23 #include "libnr/nr-coord.h"
24 #include "libnr/nr-values.h"
25 #include <libnr/nr-rotate.h>
26 #include <libnr/nr-scale.h>
27 #include <libnr/nr-translate.h>
28 #include <2geom/matrix.h>
30 namespace NR {
32 /**
33 * The Matrix class.
34 *
35 * For purposes of multiplication, points should be thought of as row vectors
36 *
37 * p = ( p[X] p[Y] 1 )
38 *
39 * to be right-multiplied by transformation matrices
40 * \verbatim
41 c[] = | c[0] c[1] 0 |
42 | c[2] c[3] 0 |
43 | c[4] c[5] 1 | \endverbatim
44 *
45 * (so the columns of the matrix correspond to the columns (elements) of the result,
46 * and the rows of the matrix correspond to columns (elements) of the "input").
47 */
48 class Matrix {
51 public:
53 /**
54 * Various forms of constructor
55 */
57 /**
58 *
59 */
60 explicit Matrix() { }
63 /**
64 *
65 */
66 Matrix(Matrix const &m) {
68 NR::Coord const *src = m._c;
69 NR::Coord *dest = _c;
71 *dest++ = *src++; //0
72 *dest++ = *src++; //1
73 *dest++ = *src++; //2
74 *dest++ = *src++; //3
75 *dest++ = *src++; //4
76 *dest = *src ; //5
78 }
81 Matrix(Geom::Matrix const &m) {
82 NR::Coord *dest = _c;
84 *dest++ = m[0];
85 *dest++ = m[1];
86 *dest++ = m[2];
87 *dest++ = m[3];
88 *dest++ = m[4];
89 *dest = m[5];
90 }
92 /**
93 *
94 */
95 Matrix(double c0, double c1,
96 double c2, double c3,
97 double c4, double c5) {
99 NR::Coord *dest = _c;
101 *dest++ = c0; //0
102 *dest++ = c1; //1
103 *dest++ = c2; //2
104 *dest++ = c3; //3
105 *dest++ = c4; //4
106 *dest = c5; //5
108 }
112 /**
113 *
114 */
115 Matrix &operator=(Matrix const &m) {
117 NR::Coord const *src = m._c;
118 NR::Coord *dest = _c;
120 *dest++ = *src++; //0
121 *dest++ = *src++; //1
122 *dest++ = *src++; //2
123 *dest++ = *src++; //3
124 *dest++ = *src++; //4
125 *dest = *src ; //5
127 return *this;
128 }
133 /**
134 *
135 */
136 explicit Matrix(scale const &sm) {
138 NR::Coord *dest = _c;
140 *dest++ = sm[X]; //0
141 *dest++ = 0.0; //1
142 *dest++ = 0.0; //2
143 *dest++ = sm[Y]; //3
144 *dest++ = 0.0; //4
145 *dest = 0.0; //5
147 }
154 /**
155 *
156 */
157 explicit Matrix(rotate const &r) {
159 NR::Coord *dest = _c;
161 *dest++ = r.vec[X]; //0
162 *dest++ = r.vec[Y]; //1
163 *dest++ = -r.vec[Y]; //2
164 *dest++ = r.vec[X]; //3
165 *dest++ = 0.0; //4
166 *dest = 0.0; //5
168 }
173 /**
174 *
175 */
176 explicit Matrix(translate const &tm) {
178 NR::Coord *dest = _c;
180 *dest++ = 1.0; //0
181 *dest++ = 0.0; //1
182 *dest++ = 0.0; //2
183 *dest++ = 1.0; //3
184 *dest++ = tm[X]; //4
185 *dest = tm[Y]; //5
186 }
189 /**
190 *
191 */
192 bool test_identity() const;
195 /**
196 *
197 */
198 bool is_translation(Coord const eps = 1e-6) const;
200 /**
201 *
202 */
203 bool is_scale(Coord const eps = 1e-6) const;
205 /**
206 *
207 */
208 bool is_rotation(Coord const eps = 1e-6) const;
211 /**
212 *
213 */
214 Matrix inverse() const;
218 /**
219 *
220 */
221 inline Coord &operator[](int const i) {
222 return _c[i];
223 }
227 /**
228 *
229 */
230 inline Coord operator[](int const i) const {
231 return _c[i];
232 }
234 inline operator Geom::Matrix() const {
235 return Geom::Matrix(_c[0], _c[1], _c[2], _c[3], _c[4], _c[5]);
236 }
238 /**
239 *
240 */
241 void set_identity();
243 /**
244 *
245 */
246 Coord det() const;
249 /**
250 *
251 */
252 Coord descrim2() const;
255 /**
256 *
257 */
258 Coord descrim() const;
261 private:
264 NR::Coord _c[6];
265 };
267 /** A function to print out the Matrix (for debugging) */
268 inline std::ostream &operator<< (std::ostream &out_file, const NR::Matrix &m) {
269 out_file << "A: " << m[0] << " C: " << m[2] << " E: " << m[4] << "\n";
270 out_file << "B: " << m[1] << " D: " << m[3] << " F: " << m[5] << "\n";
271 return out_file;
272 }
274 } /* namespace NR */
282 /** \note
283 * Discussion of splitting up nr-matrix.h into lots of little files:
284 *
285 * Advantages:
286 *
287 * - Reducing amount of recompilation necessary when anything changes.
288 *
289 * - Hopefully also reducing compilation time by reducing the number of inline
290 * function definitions encountered by the compiler for a given .o file.
291 * (No timing comparisons done yet. On systems without much memory available
292 * for caching, this may be outweighed by additional I/O costs.)
293 *
294 * Disadvantages:
295 *
296 * - More #include lines necessary per file. If a compile fails due to
297 * not having all the necessary #include lines, then the developer needs
298 * to spend some time working out what #include to add.
299 */
301 #endif /* !__NR_MATRIX_H__ */
304 /*
305 Local Variables:
306 mode:c++
307 c-file-style:"stroustrup"
308 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
309 indent-tabs-mode:nil
310 fill-column:99
311 End:
312 */
313 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :