Code

No more NRMatrix or NRPoint.
[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>
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();
228         
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;
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 :