Code

Super duper mega (fun!) commit: replaced encoding=utf-8 with fileencoding=utf-8 in...
[inkscape.git] / src / libnr / nr-matrix.h
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();
242         
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;
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:fileencoding=utf-8:textwidth=99 :