NCBI C++ ToolKit
matrix4.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef GUI_MATH___MATRIX4___HPP
2 #define GUI_MATH___MATRIX4___HPP
3 
4 /* $Id: matrix4.hpp 30863 2014-07-31 15:41:12Z falkrb $
5  * ===========================================================================
6  *
7  * PUBLIC DOMAIN NOTICE
8  * National Center for Biotechnology Information
9  *
10  * This software / database is a "United States Government Work" under the
11  * terms of the United States Copyright Act. It was written as part of
12  * the author's official duties as a United States Government employee and
13  * thus cannot be copyrighted. This software / database is freely available
14  * to the public for use. The National Library of Medicine and the U.S.
15  * Government have not placed any restriction on its use or reproduction.
16  *
17  * Although all reasonable efforts have been taken to ensure the accuracy
18  * and reliability of the software and data, the NLM and the U.S.
19  * Government do not and cannot warrant the performance or results that
20  * may be obtained by using this software or data. The NLM and the U.S.
21  * Government disclaim all warranties, express or implied, including
22  * warranties of performance, merchantability or fitness for any particular
23  * purpose.
24  *
25  * Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Authors: Mike DiCuccio
30  *
31  * File Description:
32  *
33  */
34 
35 
36 #include <corelib/ncbistd.hpp>
37 #include <gui/utils/vect4.hpp>
38 
39 /** @addtogroup GUI_MATH
40  *
41  * @{
42  */
43 
45 
46 
47 template <class T>
48 class CMatrix4
49 {
50 public:
51  // ctors
54  CMatrix4 (T,T,T,T, T,T,T,T, T,T,T,T, T,T,T,T);
55  CMatrix4 (T[16]);
56  CMatrix4 (T[4][4]);
57 
58  //
59  // operators
60  //
61 
62  // operator: index
63  const T& operator() (int i, int j) const { return m_Data[i * 4+j]; }
64  T& operator() (int i, int j) { return m_Data[i * 4+j]; }
65 
66  // operator: index
67  const T& operator[] (int i) const { return m_Data[i]; }
68  T& operator[] (int i) { return m_Data[i]; }
69 
70 
71  // operator: addition
74 
75  // operator: subtraction
78 
79  // operator: multiplication
82 
83  // operator: division
85 
86  //
87  // named functions
88 
89 
90  // transpose the current matrix
91  void Transpose();
92 
93  // make the current matrix an identity matrix
94  void Identity();
95 
96  // clear the current matrix to a given value
97  void Clear(T x = (T)0);
98 
99  // return the determinant of the current matrix
100  T Determinant() const;
101 
102  // data accessor
103  const T* GetData() const { return m_Data; }
104  T* GetData() { return m_Data; }
105 
106  // return a vector representing a row
107  CVect4<T> Row(int) const;
108 
109  // return a vector representing a column
110  CVect4<T> Column(int) const;
111 
112 private:
113  T m_Data[16];
114 
115 };
116 
117 
119 
120 //
121 // global operations
122 // this is included after the class declaration
123 #include <gui/utils/globals.hpp>
124 
126 
127 
128 //
129 // default ctor
130 template <class T> inline
132 {
133  Clear(T(0));
134 }
135 
136 //
137 // conversion ctors
138 template <class T> inline
140 {
141  Clear(val);
142 }
143 
144 
145 template <class T> inline
146 CMatrix4<T>::CMatrix4(T m1, T m2, T m3, T m4,
147  T m5, T m6, T m7, T m8,
148  T m9, T m10, T m11, T m12,
149  T m13, T m14, T m15, T m16)
150 {
151  m_Data[ 0] = m1; m_Data[ 1] = m2; m_Data[ 2] = m3; m_Data[ 3] = m4;
152  m_Data[ 4] = m5; m_Data[ 5] = m6; m_Data[ 6] = m7; m_Data[ 7] = m8;
153  m_Data[ 8] = m9; m_Data[ 9] = m10; m_Data[10] = m11; m_Data[11] = m12;
154  m_Data[12] = m13; m_Data[13] = m14; m_Data[14] = m15; m_Data[15] = m16;
155 }
156 
157 
158 template <class T> inline
160 {
161  for (int i = 0; i < 16; ++i) {
162  m_Data[i] = m[i];
163  }
164 }
165 
166 
167 template <class T> inline
169 {
170  m_Data[ 0] = m[0][0];
171  m_Data[ 1] = m[0][1];
172  m_Data[ 2] = m[0][2];
173  m_Data[ 3] = m[0][3];
174 
175  m_Data[ 4] = m[1][0];
176  m_Data[ 5] = m[1][1];
177  m_Data[ 6] = m[1][2];
178  m_Data[ 7] = m[1][3];
179 
180  m_Data[ 8] = m[2][0];
181  m_Data[ 9] = m[2][1];
182  m_Data[10] = m[2][2];
183  m_Data[11] = m[2][3];
184 
185  m_Data[12] = m[3][0];
186  m_Data[13] = m[3][1];
187  m_Data[14] = m[3][2];
188  m_Data[15] = m[3][3];
189 }
190 
191 
192 //
193 // addition: scalar
194 template <class T> inline CMatrix4<T>&
196 {
197  for (int i = 0; i < 16; ++i) {
198  m_Data[i] += scalar;
199  }
200 
201  return *this;
202 }
203 
204 //
205 // addition: matrix
206 template <class T> inline CMatrix4<T>&
208 {
209  for (int i = 0; i < 16; ++i) {
210  m_Data[i] += m[i];
211  }
212 
213  return *this;
214 }
215 
216 //
217 // subtraction: scalar
218 template <class T> inline CMatrix4<T>&
220 {
221  for (int i = 0; i < 16; ++i) {
222  m_Data[i] -= scalar;
223  }
224 
225  return *this;
226 }
227 
228 //
229 // subtraction: matrix
230 template <class T> inline CMatrix4<T>&
232 {
233  for (int i = 0; i < 16; ++i) {
234  m_Data[i] -= m[i];
235  }
236 
237  return *this;
238 }
239 
240 
241 //
242 // multiplication: scalar
243 template <class T> inline CMatrix4<T>&
245 {
246  for (int i = 0; i < 16; ++i) {
247  m_Data[i] *= scalar;
248  }
249 
250  return *this;
251 }
252 
253 //
254 // multiplication: matrix
255 template <class T> inline CMatrix4<T>&
257 {
258  // given
259  //
260  // a b c 1 2 3
261  // d e f 4 5 6
262  // g h i 7 8 9
263  //
264  // result is:
265  // (a1 + b4 + c7) (a2 + b5 + c8) (a3 + b6 + c9)
266  // (d1 + e4 + f7) (d2 + e5 + f8) (d3 + e6 + f9)
267  // (g1 + h4 + i7) (g2 + h5 + i8) (g3 + h6 + i9)
268 
269  T t0;
270  T t1;
271  T t2;
272  T t3;
273 
274  t0 = m_Data[ 0] * m[ 0] + m_Data[ 1] * m[ 4] +
275  m_Data[ 2] * m[ 8] + m_Data[ 3] * m[12];
276  t1 = m_Data[ 0] * m[ 1] + m_Data[ 1] * m[ 5] +
277  m_Data[ 2] * m[ 9] + m_Data[ 3] * m[13];
278  t2 = m_Data[ 0] * m[ 2] + m_Data[ 1] * m[ 6] +
279  m_Data[ 2] * m[10] + m_Data[ 3] * m[14];
280  t3 = m_Data[ 0] * m[ 3] + m_Data[ 1] * m[ 7] +
281  m_Data[ 2] * m[11] + m_Data[ 3] * m[15];
282  m_Data[0] = t0;
283  m_Data[1] = t1;
284  m_Data[2] = t2;
285  m_Data[3] = t3;
286 
287  t0 = m_Data[ 4] * m[ 0] + m_Data[ 5] * m[ 4] +
288  m_Data[ 6] * m[ 8] + m_Data[ 7] * m[12];
289  t1 = m_Data[ 4] * m[ 1] + m_Data[ 5] * m[ 5] +
290  m_Data[ 6] * m[ 9] + m_Data[ 7] * m[13];
291  t2 = m_Data[ 4] * m[ 2] + m_Data[ 5] * m[ 6] +
292  m_Data[ 6] * m[10] + m_Data[ 7] * m[14];
293  t3 = m_Data[ 4] * m[ 3] + m_Data[ 5] * m[ 7] +
294  m_Data[ 6] * m[11] + m_Data[ 7] * m[15];
295  m_Data[4] = t0;
296  m_Data[5] = t1;
297  m_Data[6] = t2;
298  m_Data[7] = t3;
299 
300  t0 = m_Data[ 8] * m[ 0] + m_Data[ 9] * m[ 4] +
301  m_Data[10] * m[ 8] + m_Data[11] * m[12];
302  t1 = m_Data[ 8] * m[ 1] + m_Data[ 9] * m[ 5] +
303  m_Data[10] * m[ 9] + m_Data[11] * m[13];
304  t2 = m_Data[ 8] * m[ 2] + m_Data[ 9] * m[ 6] +
305  m_Data[10] * m[10] + m_Data[11] * m[14];
306  t3 = m_Data[ 8] * m[ 3] + m_Data[ 9] * m[ 7] +
307  m_Data[10] * m[11] + m_Data[11] * m[15];
308  m_Data[ 8] = t0;
309  m_Data[ 9] = t1;
310  m_Data[10] = t2;
311  m_Data[11] = t3;
312 
313  t0 = m_Data[12] * m[ 0] + m_Data[13] * m[ 4] +
314  m_Data[14] * m[ 8] + m_Data[15] * m[12];
315  t1 = m_Data[12] * m[ 1] + m_Data[13] * m[ 5] +
316  m_Data[14] * m[ 9] + m_Data[15] * m[13];
317  t2 = m_Data[12] * m[ 2] + m_Data[13] * m[ 6] +
318  m_Data[14] * m[10] + m_Data[15] * m[14];
319  t3 = m_Data[12] * m[ 3] + m_Data[13] * m[ 7] +
320  m_Data[14] * m[11] + m_Data[15] * m[15];
321  m_Data[12] = t0;
322  m_Data[13] = t1;
323  m_Data[14] = t2;
324  m_Data[15] = t3;
325 
326  return *this;
327 }
328 
329 //
330 // division: scalar
331 template <class T> inline CMatrix4<T>&
333 {
334  scalar = T(1) / scalar;
335 
336  for (int i = 0; i < 16; ++i) {
337  m_Data[i] *= scalar;
338  }
339 
340  return *this;
341 }
342 
343 
344 //
345 // transpose a matrix
346 template <class T> inline void
348 {
349  // given
350  // a b c d
351  // e f g h
352  // i j k l
353  // m n o p
354  //
355  // result is
356  // a e i m
357  // b f j n
358  // c g k o
359  // d h l p
360 
361 
362  std::swap(m_Data[ 1], m_Data[ 4]);
363  std::swap(m_Data[ 2], m_Data[ 8]);
364  std::swap(m_Data[ 3], m_Data[12]);
365  std::swap(m_Data[ 6], m_Data[ 9]);
366  std::swap(m_Data[ 7], m_Data[13]);
367  std::swap(m_Data[11], m_Data[14]);
368 }
369 
370 //
371 // create a unit matrix
372 template <class T> inline void
374 {
375  Clear((T)0);
376  m_Data[ 0] = 1;
377  m_Data[ 5] = 1;
378  m_Data[10] = 1;
379  m_Data[15] = 1;
380 }
381 
382 //
383 // clear a matrix so that all its values are the passed value
384 template <class T> inline void
386 {
387  for (int i = 0; i < 16; ++i) {
388  m_Data[i] = value;
389  }
390 }
391 
392 
393 //
394 // return a row as a vector
395 template <class T> inline CVect4<T>
396 CMatrix4<T>::Row(int i) const
397 {
398  int row_idx = i<<2;
399  return CVect4<T> (m_Data[row_idx ],
400  m_Data[row_idx + 1],
401  m_Data[row_idx + 2] ,
402  m_Data[row_idx + 3]);
403 }
404 
405 
406 //
407 // return a column as a vector
408 template <class T> inline CVect4<T>
410 {
411  return CVect4<T> (m_Data[ j],
412  m_Data[ 4 + j],
413  m_Data[ 8 + j],
414  m_Data[12 + j]);
415 }
416 
417 
418 //
419 // return the determinant of a 3x3 matrix
420 template <class T> inline T
422 {
423  // given
424  // a b c d
425  // e f g h
426  // i j k l
427  // m n o p
428  //
429  // determinant is
430  //
431  // + a[ f(kp - lo) - g(jp - ln) + h(jo - kn) ]
432  // - b[ e(kp - lo) - g(ip - lm) + h(io - km) ]
433  // + c[ e(jp - ln) - f(ip - lm) + h(in - jm) ]
434  // - d[ e(jo - kn) - f(io - km) + g(in - jm) ]
435 
436  T det;
437 
438  T kp = m_Data[10]*m_Data[15];
439  T lo = m_Data[11]*m_Data[14];
440  T jp = m_Data[ 9]*m_Data[15];
441  T ln = m_Data[11]*m_Data[13];
442  T jo = m_Data[ 9]*m_Data[14];
443  T kn = m_Data[10]*m_Data[13];
444 
445  det = m_Data[0] * ( m_Data[5]*(kp - lo)
446  - m_Data[6]*(jp - ln)
447  + m_Data[7]*(jo - kn) );
448 
449  T ip = m_Data[ 8]*m_Data[15];
450  T lm = m_Data[11]*m_Data[12];
451  T io = m_Data[ 8]*m_Data[14];
452  T km = m_Data[10]*m_Data[12];
453 
454  det -= m_Data[1] * ( m_Data[4]*(kp - lo)
455  - m_Data[6]*(ip - lm)
456  + m_Data[7]*(io - km) );
457 
458  T in = m_Data[ 8]*m_Data[13];
459  T jm = m_Data[ 9]*m_Data[12];
460 
461  det += m_Data[3] * ( m_Data[4]*(jp - ln)
462  - m_Data[5]*(ip - lm)
463  + m_Data[7]*(in - jm) );
464 
465  det -= m_Data[4] * ( m_Data[4]*(jo - kn)
466  - m_Data[5]*(io - km)
467  + m_Data[6]*(in - jm) );
468 
469  return det;
470 }
471 
472 
474 
475 /* @} */
476 
477 #endif // GUI_MATH___MATRIX4___HPP
Definition: vect4.hpp:49
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define T(s)
Definition: common.h:230
static const char ip[]
Definition: des.c:75
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
const T & operator[](int i) const
Definition: matrix4.hpp:67
T * GetData()
Definition: matrix4.hpp:104
CVect4< T > Row(int) const
Definition: matrix4.hpp:396
const T & operator()(int i, int j) const
Definition: matrix4.hpp:63
T m_Data[16]
Definition: matrix4.hpp:113
CMatrix4(T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T)
Definition: matrix4.hpp:146
CMatrix4< T > & operator/=(T)
Definition: matrix4.hpp:332
CMatrix4< T > & operator-=(T)
Definition: matrix4.hpp:219
CVect4< T > Column(int) const
Definition: matrix4.hpp:409
void Clear(T x=(T) 0)
Definition: matrix4.hpp:385
CMatrix4< T > & operator+=(T)
Definition: matrix4.hpp:195
CMatrix4< T > & operator*=(T)
Definition: matrix4.hpp:244
void Transpose()
Definition: matrix4.hpp:347
CMatrix4(T[4][4])
Definition: matrix4.hpp:168
CMatrix4(T val)
Definition: matrix4.hpp:139
void Identity()
Definition: matrix4.hpp:373
const T * GetData() const
Definition: matrix4.hpp:103
CMatrix4(T[16])
Definition: matrix4.hpp:159
CMatrix4()
Definition: matrix4.hpp:131
T Determinant() const
Definition: matrix4.hpp:421
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
int i
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
std::istream & in(std::istream &in_, double &x_)
Modified on Wed Sep 04 15:05:02 2024 by modify_doxy.py rev. 669887