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>
29 namespace NR {
31 /**
32 * The Matrix class.
33 *
34 * For purposes of multiplication, points should be thought of as row vectors
35 *
36 * p = ( p[X] p[Y] 1 )
37 *
38 * to be right-multiplied by transformation matrices
39 * \verbatim
40 c[] = | c[0] c[1] 0 |
41 | c[2] c[3] 0 |
42 | c[4] c[5] 1 | \endverbatim
43 *
44 * (so the columns of the matrix correspond to the columns (elements) of the result,
45 * and the rows of the matrix correspond to columns (elements) of the "input").
46 */
47 class Matrix {
50 public:
52 /**
53 * Various forms of constructor
54 */
56 /**
57 *
58 */
59 explicit Matrix() { }
62 /**
63 *
64 */
65 Matrix(Matrix const &m) {
67 NR::Coord const *src = m._c;
68 NR::Coord *dest = _c;
70 *dest++ = *src++; //0
71 *dest++ = *src++; //1
72 *dest++ = *src++; //2
73 *dest++ = *src++; //3
74 *dest++ = *src++; //4
75 *dest = *src ; //5
77 }
81 /**
82 *
83 */
84 Matrix(double c0, double c1,
85 double c2, double c3,
86 double c4, double c5) {
88 NR::Coord *dest = _c;
90 *dest++ = c0; //0
91 *dest++ = c1; //1
92 *dest++ = c2; //2
93 *dest++ = c3; //3
94 *dest++ = c4; //4
95 *dest = c5; //5
97 }
101 /**
102 *
103 */
104 Matrix &operator=(Matrix const &m) {
106 NR::Coord const *src = m._c;
107 NR::Coord *dest = _c;
109 *dest++ = *src++; //0
110 *dest++ = *src++; //1
111 *dest++ = *src++; //2
112 *dest++ = *src++; //3
113 *dest++ = *src++; //4
114 *dest = *src ; //5
116 return *this;
117 }
122 /**
123 *
124 */
125 explicit Matrix(scale const &sm) {
127 NR::Coord *dest = _c;
129 *dest++ = sm[X]; //0
130 *dest++ = 0.0; //1
131 *dest++ = 0.0; //2
132 *dest++ = sm[Y]; //3
133 *dest++ = 0.0; //4
134 *dest = 0.0; //5
136 }
143 /**
144 *
145 */
146 explicit Matrix(rotate const &r) {
148 NR::Coord *dest = _c;
150 *dest++ = r.vec[X]; //0
151 *dest++ = r.vec[Y]; //1
152 *dest++ = -r.vec[Y]; //2
153 *dest++ = r.vec[X]; //3
154 *dest++ = 0.0; //4
155 *dest = 0.0; //5
157 }
162 /**
163 *
164 */
165 explicit Matrix(translate const &tm) {
167 NR::Coord *dest = _c;
169 *dest++ = 1.0; //0
170 *dest++ = 0.0; //1
171 *dest++ = 0.0; //2
172 *dest++ = 1.0; //3
173 *dest++ = tm[X]; //4
174 *dest = tm[Y]; //5
175 }
178 /**
179 *
180 */
181 bool test_identity() const;
184 /**
185 *
186 */
187 bool is_translation(Coord const eps = 1e-6) const;
189 /**
190 *
191 */
192 bool is_scale(Coord const eps = 1e-6) const;
194 /**
195 *
196 */
197 bool is_rotation(Coord const eps = 1e-6) const;
200 /**
201 *
202 */
203 Matrix inverse() const;
207 /**
208 *
209 */
210 inline Coord &operator[](int const i) {
211 return _c[i];
212 }
216 /**
217 *
218 */
219 inline Coord operator[](int const i) const {
220 return _c[i];
221 }
224 /**
225 *
226 */
227 void set_identity();
229 /**
230 *
231 */
232 Coord det() const;
235 /**
236 *
237 */
238 Coord descrim2() const;
241 /**
242 *
243 */
244 Coord descrim() const;
247 private:
250 NR::Coord _c[6];
251 };
253 /** A function to print out the Matrix (for debugging) */
254 inline std::ostream &operator<< (std::ostream &out_file, const NR::Matrix &m) {
255 out_file << "A: " << m[0] << " C: " << m[2] << " E: " << m[4] << "\n";
256 out_file << "B: " << m[1] << " D: " << m[3] << " F: " << m[5] << "\n";
257 return out_file;
258 }
260 } /* namespace NR */
268 /** \note
269 * Discussion of splitting up nr-matrix.h into lots of little files:
270 *
271 * Advantages:
272 *
273 * - Reducing amount of recompilation necessary when anything changes.
274 *
275 * - Hopefully also reducing compilation time by reducing the number of inline
276 * function definitions encountered by the compiler for a given .o file.
277 * (No timing comparisons done yet. On systems without much memory available
278 * for caching, this may be outweighed by additional I/O costs.)
279 *
280 * Disadvantages:
281 *
282 * - More #include lines necessary per file. If a compile fails due to
283 * not having all the necessary #include lines, then the developer needs
284 * to spend some time working out what #include to add.
285 */
287 #endif /* !__NR_MATRIX_H__ */
290 /*
291 Local Variables:
292 mode:c++
293 c-file-style:"stroustrup"
294 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
295 indent-tabs-mode:nil
296 fill-column:99
297 End:
298 */
299 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :