~lib2geom-hackers/lib2geom/trunk

« back to all changes in this revision

Viewing changes to matrix.h

  • Committer: njh
  • Date: 2006-05-22 11:50:24 UTC
  • Revision ID: svn-v4:4601daaa-0314-0410-9a8b-c964a3c23b6b:trunk/lib2geom:1
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef __Geom_MATRIX_H__
 
2
#define __Geom_MATRIX_H__
 
3
 
 
4
/** \file
 
5
 * Definition of Geom::Matrix types.
 
6
 *
 
7
 * \note Operator functions (e.g. Matrix * Matrix etc.) are mostly in
 
8
 * libnr/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
 *     Geom::Matrix class version of the above.
 
16
 *
 
17
 * This code is in public domain.
 
18
 */
 
19
 
 
20
//#include <glib/gmessages.h>
 
21
 
 
22
#include "coord.h"
 
23
#include "values.h"
 
24
#include "rotate.h"
 
25
#include "scale.h"
 
26
#include "translate.h"
 
27
 
 
28
namespace Geom {
 
29
 
 
30
/**
 
31
 * The Matrix class.
 
32
 * 
 
33
 * For purposes of multiplication, points should be thought of as row vectors
 
34
 *
 
35
 *    p = ( p[X] p[Y]  1  )
 
36
 *
 
37
 * to be right-multiplied by transformation matrices
 
38
 * \verbatim
 
39
    c[] = | c[0] c[1]  0  |
 
40
          | c[2] c[3]  0  |
 
41
          | c[4] c[5]  1  |                           \endverbatim
 
42
 *
 
43
 * (so the columns of the matrix correspond to the columns (elements) of the result,
 
44
 * and the rows of the matrix correspond to columns (elements) of the "input").
 
45
 */
 
46
class Matrix {
 
47
 
 
48
 
 
49
    public:
 
50
 
 
51
    /**
 
52
     * Various forms of constructor
 
53
     */
 
54
 
 
55
    /**
 
56
     *
 
57
     */
 
58
    explicit Matrix() { }
 
59
 
 
60
 
 
61
    /**
 
62
     *
 
63
     */
 
64
    Matrix(Matrix const &m) {
 
65
 
 
66
        Geom::Coord const *src = m._c;
 
67
        Geom::Coord *dest      = _c;
 
68
 
 
69
        *dest++ = *src++;  //0
 
70
        *dest++ = *src++;  //1
 
71
        *dest++ = *src++;  //2
 
72
        *dest++ = *src++;  //3
 
73
        *dest++ = *src++;  //4
 
74
        *dest   = *src  ;  //5
 
75
 
 
76
    }
 
77
 
 
78
 
 
79
 
 
80
 
 
81
 
 
82
 
 
83
    /**
 
84
     *
 
85
     */
 
86
    Matrix(double c0, double c1,
 
87
           double c2, double c3,
 
88
           double c4, double c5) {
 
89
 
 
90
        Geom::Coord *dest = _c;
 
91
 
 
92
        *dest++ = c0;  //0
 
93
        *dest++ = c1;  //1
 
94
        *dest++ = c2;  //2
 
95
        *dest++ = c3;  //3
 
96
        *dest++ = c4;  //4
 
97
        *dest   = c5;  //5
 
98
 
 
99
    }
 
100
 
 
101
 
 
102
 
 
103
    /**
 
104
     *
 
105
     */
 
106
    Matrix &operator=(Matrix const &m) {
 
107
 
 
108
        Geom::Coord const *src = m._c;
 
109
        Geom::Coord *dest      = _c;
 
110
 
 
111
        *dest++ = *src++;  //0
 
112
        *dest++ = *src++;  //1
 
113
        *dest++ = *src++;  //2
 
114
        *dest++ = *src++;  //3
 
115
        *dest++ = *src++;  //4
 
116
        *dest   = *src  ;  //5
 
117
 
 
118
        return *this;
 
119
    }
 
120
 
 
121
 
 
122
 
 
123
 
 
124
    /**
 
125
     *
 
126
     */
 
127
    explicit Matrix(scale const &sm) {
 
128
 
 
129
        Geom::Coord *dest  = _c;
 
130
 
 
131
        *dest++ = sm[X]; //0
 
132
        *dest++ = 0.0;   //1
 
133
        *dest++ = 0.0;   //2
 
134
        *dest++ = sm[Y]; //3
 
135
        *dest++ = 0.0;   //4
 
136
        *dest   = 0.0;   //5
 
137
 
 
138
    }
 
139
 
 
140
 
 
141
 
 
142
 
 
143
 
 
144
 
 
145
    /**
 
146
     *
 
147
     */
 
148
    explicit Matrix(rotate const &r) {
 
149
 
 
150
        Geom::Coord *dest  = _c;
 
151
 
 
152
        *dest++ =  r.vec[X]; //0
 
153
        *dest++ =  r.vec[Y]; //1
 
154
        *dest++ = -r.vec[Y]; //2
 
155
        *dest++ =  r.vec[X]; //3
 
156
        *dest++ =  0.0;      //4
 
157
        *dest   =  0.0;      //5
 
158
 
 
159
    }
 
160
 
 
161
 
 
162
 
 
163
 
 
164
    /**
 
165
     *
 
166
     */
 
167
    explicit Matrix(translate const &tm) {
 
168
 
 
169
        Geom::Coord *dest  = _c;
 
170
 
 
171
        *dest++ =  1.0;   //0
 
172
        *dest++ =  0.0;   //1
 
173
        *dest++ =  0.0;   //2
 
174
        *dest++ =  1.0;   //3
 
175
        *dest++ =  tm[X]; //4
 
176
        *dest   =  tm[Y]; //5
 
177
    }
 
178
 
 
179
 
 
180
 
 
181
 
 
182
    /**
 
183
     *
 
184
     */
 
185
    bool test_identity() const;
 
186
 
 
187
 
 
188
    /**
 
189
     *
 
190
     */
 
191
    bool is_translation(Coord const eps = 1e-6) const;
 
192
 
 
193
 
 
194
    /**
 
195
     *
 
196
     */
 
197
    Matrix inverse() const;
 
198
 
 
199
 
 
200
    /**
 
201
     *
 
202
     */
 
203
    Matrix &operator*=(Matrix const &other);
 
204
 
 
205
 
 
206
    /**
 
207
     *
 
208
     */
 
209
    Matrix &operator*=(scale const &other);
 
210
 
 
211
 
 
212
 
 
213
    /**
 
214
     *
 
215
     */
 
216
    Matrix &operator*=(translate const &other) {
 
217
        _c[4] += other[X];
 
218
        _c[5] += other[Y];
 
219
        return *this;
 
220
    }
 
221
 
 
222
 
 
223
 
 
224
    /**
 
225
     *
 
226
     */
 
227
    inline Coord &operator[](int const i) {
 
228
        return _c[i];
 
229
    }
 
230
 
 
231
 
 
232
 
 
233
    /**
 
234
     *
 
235
     */
 
236
    inline Coord operator[](int const i) const {
 
237
        return _c[i];
 
238
    }
 
239
 
 
240
 
 
241
    /**
 
242
     *
 
243
     */
 
244
    void set_identity();
 
245
        
 
246
    /**
 
247
     *
 
248
     */
 
249
    Coord det() const;
 
250
 
 
251
 
 
252
    /**
 
253
     *
 
254
     */
 
255
    Coord descrim2() const;
 
256
 
 
257
 
 
258
    /**
 
259
     *
 
260
     */
 
261
    Coord descrim() const;
 
262
 
 
263
 
 
264
    /**
 
265
     *
 
266
     */
 
267
    double expansion() const;
 
268
 
 
269
 
 
270
    /**
 
271
     *
 
272
     */
 
273
    double expansionX() const;
 
274
 
 
275
 
 
276
    /**
 
277
     *
 
278
     */
 
279
    double expansionY() const;
 
280
        
 
281
    // legacy
 
282
 
 
283
 
 
284
    /**
 
285
     *
 
286
     */
 
287
    Matrix &assign(Coord const *array);
 
288
 
 
289
 
 
290
    /**
 
291
     *
 
292
     */
 
293
    Coord *copyto(Coord *array) const;
 
294
 
 
295
 
 
296
 
 
297
    private:
 
298
 
 
299
 
 
300
    Geom::Coord _c[6];
 
301
};
 
302
 
 
303
/** A function to print out the Matrix (for debugging) */
 
304
inline std::ostream &operator<< (std::ostream &out_file, const Geom::Matrix &m) {
 
305
    out_file << "A: " << m[0] << "  C: " << m[2] << "  E: " << m[4] << "\n";
 
306
    out_file << "B: " << m[1] << "  D: " << m[3] << "  F: " << m[5] << "\n";
 
307
    return out_file;
 
308
}
 
309
 
 
310
extern void assert_close(Matrix const &a, Matrix const &b);
 
311
 
 
312
} /* namespace Geom */
 
313
 
 
314
 
 
315
 
 
316
 
 
317
 
 
318
 
 
319
 
 
320
/** \note
 
321
 * Discussion of splitting up matrix.h into lots of little files:
 
322
 *
 
323
 *   Advantages:
 
324
 *
 
325
 *    - Reducing amount of recompilation necessary when anything changes.
 
326
 *
 
327
 *    - Hopefully also reducing compilation time by reducing the number of inline
 
328
 *      function definitions encountered by the compiler for a given .o file.
 
329
 *      (No timing comparisons done yet.  On systems without much memory available
 
330
 *      for caching, this may be outweighed by additional I/O costs.)
 
331
 *
 
332
 *   Disadvantages:
 
333
 *
 
334
 *    - More #include lines necessary per file.  If a compile fails due to
 
335
 *      not having all the necessary #include lines, then the developer needs
 
336
 *      to spend some time working out what #include to add.
 
337
 */
 
338
 
 
339
#endif /* !__Geom_MATRIX_H__ */
 
340
 
 
341
 
 
342
/*
 
343
  Local Variables:
 
344
  mode:c++
 
345
  c-file-style:"stroustrup"
 
346
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
347
  indent-tabs-mode:nil
 
348
  fill-column:99
 
349
  End:
 
350
*/
 
351
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :