File: Matrix3D.hh

package info (click to toggle)
3dwm 0.3.1-8
  • links: PTS
  • area: main
  • in suites: woody
  • size: 3,368 kB
  • ctags: 2,547
  • sloc: cpp: 11,981; sh: 7,850; ansic: 851; makefile: 287; yacc: 135; lex: 92
file content (301 lines) | stat: -rw-r--r-- 7,453 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/* ------------------------------------------------------------------------
 * $Id: Matrix3D.hh,v 1.7 2001/07/30 15:18:55 elm Exp $
 *
 * This file is part of 3Dwm: The Three-Dimensional User Environment.
 *
 * 3Dwm: The Three-Dimensional User Environment:
 *	<http://www.3dwm.org>
 *
 * Chalmers Medialab
 * 	<http://www.medialab.chalmers.se>
 * 
 * ------------------------------------------------------------------------
 * File created 2000-08-11 by Niklas Elmqvist.
 *
 * Copyright (c) 2000, 2001 Niklas Elmqvist <elm@3dwm.org>.
 * ------------------------------------------------------------------------
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 * ------------------------------------------------------------------------
 */

#ifndef _Matrix3D_hh_
#define _Matrix3D_hh_

// -- System Includes
#include <iostream>

// -- Local Includes
#include "Math.hh"

// -- Class Declarations

/**
 * 4x4 3D graphics matrix class. This is _not_ a general matrix class!
 * Many of the operations (notably matrix inversion) here are specific
 * to 3D transformation matrices. For general, MxN-dimensional matrices,
 * we should have a look at MTL, the Matrix Template Library, at
 * <http://lsc.nd.edu/research/mtl/>.
 **/
class Matrix3D {

public:
    
    /**
     * Constructor.
     **/
    Matrix3D() { clear(); }
    
    /**
     * Constructor.
     **/
    Matrix3D(const float m[4][4]) { load(m); }

    /**
     * Destructor.
     **/
    ~Matrix3D() { }
    
    /**
     * Retrieve the number of rows.
     *
     * @return the number of rows.
     **/
    int rows() const { return _dim; }
    
    /**
     * Retrieve the number of columns.
     *
     * @return the number of columns.
     **/
    int columns() const { return _dim; }
    
    /**
     * Clear the matrix.
     *
     * @param f the value to fill in the matrix with.
     **/
    void clear(float f = 0);
    
    /**
     * Build the identity matrix.
     **/
    void identity();

    /**
     * Transpose the matrix.
     **/
    void transpose();

    /**
     * Invert the matrix. Note that this is NOT a general matrix
     * inversion operation! Using this operation for non-3D-like
     * transformation matrices will produce erratic results (notably,
     * the 4th row will always be [0 0 0 1]).
     **/
    void invert();

    /**
     * Compute the matrix inverse and return it.
     * 
     * @return inverse matrix.
     **/
    Matrix3D inverse() const;

    /**
     * Compute the matrix determinant.
     **/
    float determinant() const;
    
    /**
     * Element access operator.
     *
     * @param r the row number.
     * @param c the column number.
     * @return the value.
     **/
    inline float &operator () (int r, int c) {
	return val(r, c);
    }
    
    /**
     * Element access operator (constant).
     *
     * @param r the row number.
     * @param c the column number.
     * @return the value.
     **/
    inline float operator () (int r, int c) const {
	return val(r, c);
    }
    
    /**
     * Matrix multiplication operator.
     *
     * @param m the matrix to multiply with. 
     * @return the resulting matrix.
     **/
    Matrix3D operator * (const Matrix3D &m) const;
    
    /**
     * Matrix addition operator.
     *
     * @param m the matrix to add with. 
     * @return the resulting matrix.
     **/
    Matrix3D operator + (const Matrix3D &m) const;

    /**
     * Matrix subtraction operator.
     *
     * @param m the matrix to subtract with.
     * @return the resulting matrix.
     **/
    Matrix3D operator - (const Matrix3D &m) const;

    /**
     * Scalar multiplication operator.
     * 
     * @param f the scalar.
     * @return the resulting matrix.
     **/
    Matrix3D operator * (float f) const;

    /**
     * Scalar multiplication operator. (friend function)
     * 
     * @param f the scalar.
     * @param m the matrix.
     * @return the resulting matrix.
     **/
    friend Matrix3D operator * (float f, const Matrix3D &m) {
	return m * f;
    }

    /**
     * Scalar addition operator.
     * 
     * @param f the scalar.
     * @return the resulting matrix.
     **/
    Matrix3D operator + (float f) const;

    /**
     * Scalar subtraction operator.
     * 
     * @param f the scalar.
     * @return the resulting matrix.
     **/
    Matrix3D operator - (float f) const;

    /**
     * Scalar subtraction operator.
     * 
     * @param f the scalar.
     * @return the resulting matrix.
     **/
    Matrix3D operator / (float f) const;
    
    /**
     * Load the matrix with external data.
     *
     * @param m a 4x4 matrix of float values to load.
     **/
    void load(const float m[4][4]) {
	for (int i = 0; i < _dim; i++) 
	    for (int j = 0; j < _dim; j++) 
		val(i, j) = m[i][j];
    }
    
    /**
     * Store internal matrix data to an array.
     * 
     * @param m a 4x4 matrix of float values to store to.
     **/
    void store(float m[4][4]) const {
	for (int i = 0; i < _dim; i++) 
	    for (int j = 0; j < _dim; j++) 
		m[i][j] = val(i, j);
    }

    /**
     * Retrieve the matrix data as a raw array.
     * 
     * @return const pointer to array of floats representing matrix.
     **/
    const float *data() const {
	return (float *) _data;
    }
    
    /**
     * Retrieve matrix dimension (always 4).
     *
     * @return matrix dimension.
     **/
    static int dim() {
	return _dim; 
    }

    /**
     * Matrix output operator.
     **/
    friend std::ostream &operator << (std::ostream &f, const Matrix3D &v);
    
private:
    
    /// Element access utility function
    inline float &val(int i, int j) { return _data[i * _dim + j]; }

    /// Element access utility function (constant)
    inline float val(int i, int j) const { return _data[i * _dim + j]; }

    /// Element access utility function (general array)
    inline float &val(float *f, int i, int j) { return f[i * _dim + j]; }

    /// Matrix dimension
    static const int _dim = 4;

    /// Matrix data
    float _data[_dim * _dim];
};
    
/**
 * Matrix equality operator (uses an epsilon precision tolerance).
 *
 * @param m the matrix to compare with.
 * @return true if the matrices are equal. 
 **/
inline bool operator == (const Matrix3D &a, const Matrix3D &b)
{
    // @@@Use epsilon tolerance here!
    for (int i = 0; i < Matrix3D::dim(); i++) 
	for (int j = 0; j < Matrix3D::dim(); j++) 
	    if (Math::equal(a(i, j), b(i, j)) == false)
		return false;
    return true;
}

/**
 * Matrix inequality operator (uses an epsilon precision tolerance).
 *
 * @param m the matrix to compare with.
 * @return false if the matrices are equal. 
 **/
inline bool operator != (const Matrix3D &a, const Matrix3D &b)
{
    return !(a == b);
}

#endif /* Matrix3D.hh */