Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
Matrix2.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef Matrix2_INCLUDE_ONCE
33 #define Matrix2_INCLUDE_ONCE
34 
35 #include <vlCore/checks.hpp>
36 #include <vlCore/Vector2.hpp>
37 #include <cstring> // memcpy
38 
39 namespace vl
40 {
41  //-----------------------------------------------------------------------------
42  // Matrix2
43  //-----------------------------------------------------------------------------
48  template<typename T_Scalar>
49  class Matrix2
50  {
51  public:
52  typedef T_Scalar scalar_type;
53  //-----------------------------------------------------------------------------
54  template<typename T>
55  explicit Matrix2(const Matrix2<T>& m)
56  {
57  e(0,0) = (T_Scalar)m.e(0,0); e(1,0) = (T_Scalar)m.e(1,0);
58  e(0,1) = (T_Scalar)m.e(0,1); e(1,1) = (T_Scalar)m.e(1,1);
59  }
60  //-----------------------------------------------------------------------------
62  {
63  setIdentity();
64  }
65  //-----------------------------------------------------------------------------
66  explicit Matrix2(T_Scalar n)
67  {
68  setIdentity();
69  e(0,0) = e(1,1) = n;
70  }
71  //-----------------------------------------------------------------------------
72  explicit Matrix2(T_Scalar e00, T_Scalar e01,
73  T_Scalar e10, T_Scalar e11 )
74  {
75  e(0,0) = e00; e(0,1) = e01;
76  e(1,0) = e10; e(1,1) = e11;
77  }
78  //-----------------------------------------------------------------------------
79  Matrix2& fill(T_Scalar val)
80  {
81  e(0,0) = e(1,0) =
82  e(0,1) = e(1,1) = val;
83  return *this;
84  }
85  //-----------------------------------------------------------------------------
86  T_Scalar diff(const Matrix2& other) const
87  {
88  T_Scalar err = 0;
89  for(int i=0; i<2; ++i)
90  for(int j=0; j<2; ++j)
91  if (e(j,i) > other.e(j,i)) // avoid fabs/abs
92  err += e(j,i) - other.e(j,i);
93  else
94  err += other.e(j,i) - e(j,i);
95  return err;
96  }
97  //-----------------------------------------------------------------------------
98  bool operator==(const Matrix2& m) const
99  {
100  return memcmp(m.mVec, mVec, sizeof(T_Scalar)*4) == 0;
101  }
102  //-----------------------------------------------------------------------------
103  bool operator!=(const Matrix2& m) const
104  {
105  return !operator==(m);
106  }
107  //-----------------------------------------------------------------------------
109  {
110  memcpy(mVec, m.mVec, sizeof(T_Scalar)*4);
111  return *this;
112  }
113  //-----------------------------------------------------------------------------
114  Matrix2 operator+(const Matrix2& m) const
115  {
116  Matrix2 t;
117  for(int i=0; i<2; ++i)
118  for(int j=0; j<2; ++j)
119  t.e(j,i) = e(j,i) + m.e(j,i);
120  return t;
121  }
122  //-----------------------------------------------------------------------------
124  {
125  for(int i=0; i<2; ++i)
126  for(int j=0; j<2; ++j)
127  e(j,i) += m.e(j,i);
128  return *this;
129  }
130  //-----------------------------------------------------------------------------
131  Matrix2 operator-(const Matrix2& m) const
132  {
133  Matrix2 t;
134  for(int i=0; i<2; ++i)
135  for(int j=0; j<2; ++j)
136  t.e(j,i) = e(j,i) - m.e(j,i);
137  return t;
138  }
139  //-----------------------------------------------------------------------------
141  {
142  for(int i=0; i<2; ++i)
143  for(int j=0; j<2; ++j)
144  e(j,i) -= m.e(j,i);
145  return *this;
146  }
147  //-----------------------------------------------------------------------------
149  {
150  return postMultiply(m);
151  }
152  //-----------------------------------------------------------------------------
154  {
155  Matrix2 t;
156  for(int i=0; i<2; ++i)
157  for(int j=0; j<2; ++j)
158  t.e(j,i) = -e(j,i);
159  return t;
160  }
161  //-----------------------------------------------------------------------------
162  Matrix2 operator+(T_Scalar d) const
163  {
164  Matrix2 t;
165  for(int i=0; i<2; ++i)
166  for(int j=0; j<2; ++j)
167  t.e(j,i) = e(j,i) + d;
168  return t;
169  }
170  //-----------------------------------------------------------------------------
171  Matrix2& operator+=(T_Scalar d)
172  {
173  for(int i=0; i<2; ++i)
174  for(int j=0; j<2; ++j)
175  e(j,i) += d;
176  return *this;
177  }
178  //-----------------------------------------------------------------------------
179  Matrix2 operator-(T_Scalar d) const
180  {
181  Matrix2 t;
182  for(int i=0; i<2; ++i)
183  for(int j=0; j<2; ++j)
184  t.e(j,i) = e(j,i) - d;
185  return t;
186  }
187  //-----------------------------------------------------------------------------
188  Matrix2& operator-=(T_Scalar d)
189  {
190  for(int i=0; i<2; ++i)
191  for(int j=0; j<2; ++j)
192  e(j,i) -= d;
193  return *this;
194  }
195  //-----------------------------------------------------------------------------
196  Matrix2 operator*(T_Scalar d) const
197  {
198  Matrix2 t;
199  for(int i=0; i<2; ++i)
200  for(int j=0; j<2; ++j)
201  t.e(j,i) = e(j,i) * d;
202  return t;
203  }
204  //-----------------------------------------------------------------------------
205  Matrix2& operator*=(T_Scalar d)
206  {
207  for(int i=0; i<2; ++i)
208  for(int j=0; j<2; ++j)
209  e(j,i) *= d;
210  return *this;
211  }
212  //-----------------------------------------------------------------------------
213  Matrix2 operator/(T_Scalar d) const
214  {
215  d = (T_Scalar)1 / d;
216  Matrix2 t;
217  for(int i=0; i<2; ++i)
218  for(int j=0; j<2; ++j)
219  t.e(j,i) = e(j,i) * d;
220  return t;
221  }
222  //-----------------------------------------------------------------------------
223  Matrix2& operator/=(T_Scalar d)
224  {
225  d = (T_Scalar)1 / d;
226  for(int i=0; i<2; ++i)
227  for(int j=0; j<2; ++j)
228  e(j,i) *= d;
229  return *this;
230  }
231  //-----------------------------------------------------------------------------
232  bool isIdentity() const
233  {
234  Matrix2 i;
235  return memcmp(ptr(), i.ptr(), sizeof(T_Scalar)*4) == 0;
236  }
237  //-----------------------------------------------------------------------------
238  T_Scalar* ptr()
239  {
240  return &e(0,0);
241  }
242  //-----------------------------------------------------------------------------
243  const T_Scalar* ptr() const
244  {
245  return &e(0,0);
246  }
247  //-----------------------------------------------------------------------------
249  {
250  T_Scalar tmp;
251  for(int i=0; i<2; ++i)
252  {
253  for(int j=i; j<2; ++j)
254  {
255  tmp = e(j,i);
256  e(j,i) = e(i,j);
257  e(i,j) = tmp;
258  }
259  }
260  return *this;
261  }
262  //-----------------------------------------------------------------------------
264  {
265  Matrix2 m;
266  for(int i=0; i<2; ++i)
267  for(int j=0; j<2; ++j)
268  m.e(j,i) = e(i,j);
269  return m;
270  }
271  //-----------------------------------------------------------------------------
273  {
274  for(int i=0; i<2; ++i)
275  for(int j=0; j<2; ++j)
276  dest.e(j,i) = e(i,j);
277  return dest;
278  }
279  //-----------------------------------------------------------------------------
280  bool isNull() const
281  {
282  for(int i=0; i<2; ++i)
283  for(int j=0; j<2; ++j)
284  if(mVec[j][i] != 0)
285  return false;
286  return true;
287  }
288  //-----------------------------------------------------------------------------
290  {
291  fill(0);
292  return *this;
293  }
294  //-----------------------------------------------------------------------------
295  static Matrix2& getNull(Matrix2& out)
296  {
297  out.fill(0);
298  return out;
299  }
300  //-----------------------------------------------------------------------------
301  static Matrix2 getNull()
302  {
303  return Matrix2().fill(0);
304  }
305  //-----------------------------------------------------------------------------
307  {
308  static const T_Scalar I2d[] =
309  {
310  (T_Scalar)1, (T_Scalar)0,
311  (T_Scalar)0, (T_Scalar)1
312  };
313  memcpy(mVec, I2d, sizeof(T_Scalar)*4);
314  return *this;
315  }
316  //-----------------------------------------------------------------------------
318  {
319  return Matrix2();
320  }
321  //-----------------------------------------------------------------------------
323  {
324  out.setIdentity();
325  return out;
326  }
327  //-----------------------------------------------------------------------------
328  T_Scalar getInverse(Matrix2& dest) const
329  {
330  if (&dest == this)
331  {
332  Matrix2 tmp;
333  T_Scalar det = getInverse(tmp);
334  dest = tmp;
335  return det;
336  }
337  else
338  {
339  const T_Scalar& a11 = e(0,0);
340  const T_Scalar& a12 = e(1,0);
341  const T_Scalar& a21 = e(0,1);
342  const T_Scalar& a22 = e(1,1);
343 
344  dest.fill(0);
345 
346  T_Scalar det = a11*a22-a12*a21;
347 
348  if (det != 0)
349  dest = Matrix2(+a22, -a12, -a21, +a11) / det;
350 
351  return det;
352  }
353  }
354  //-----------------------------------------------------------------------------
355  Matrix2 getInverse(T_Scalar *determinant=NULL) const
356  {
357  Matrix2 tmp;
358  T_Scalar det = getInverse(tmp);
359  if (determinant)
360  *determinant = det;
361  return tmp;
362  }
363  //-----------------------------------------------------------------------------
364  Matrix2& invert(T_Scalar *determinant=NULL)
365  {
366  T_Scalar det = getInverse(*this);
367  if (determinant)
368  *determinant = det;
369  return *this;
370  }
371  //-----------------------------------------------------------------------------
372  static Matrix2& multiply(Matrix2& out, const Matrix2& p, const Matrix2& q)
373  {
374  VL_CHECK(out.ptr() != p.ptr() && out.ptr() != q.ptr());
375 
376  out.e(0,0) = q.e(0,0)*p.e(0,0) + q.e(1,0)*p.e(0,1);
377  out.e(0,1) = q.e(0,1)*p.e(0,0) + q.e(1,1)*p.e(0,1);
378 
379  out.e(1,0) = q.e(0,0)*p.e(1,0) + q.e(1,0)*p.e(1,1);
380  out.e(1,1) = q.e(0,1)*p.e(1,0) + q.e(1,1)*p.e(1,1);
381 
382  return out;
383  }
384  //-----------------------------------------------------------------------------
386  {
388  return *this = multiply(t, *this, m);
389  }
390  //-----------------------------------------------------------------------------
392  {
394  return *this = multiply(t, m, *this);
395  }
396  //-----------------------------------------------------------------------------
397 
398  const T_Scalar& e(int i, int j) const { return mVec[j][i]; }
399  T_Scalar& e(int i, int j) { return mVec[j][i]; }
400 
401  private:
402  const Vector2<T_Scalar>& operator[](unsigned int i) const { VL_CHECK(i<2); return mVec[i]; }
403  Vector2<T_Scalar>& operator[](unsigned int i) { VL_CHECK(i<2); return mVec[i]; }
404 
405  protected:
407  };
408 
409  //-----------------------------------------------------------------------------
410  // OPERATORS
411  //-----------------------------------------------------------------------------
412  template<typename T_Scalar>
414  {
417  return t;
418  }
419  //-----------------------------------------------------------------------------
420  template<typename T_Scalar>
421  inline Matrix2<T_Scalar> operator+(T_Scalar d, const Matrix2<T_Scalar>& m)
422  {
423  return m + d;
424  }
425  //-----------------------------------------------------------------------------
426  template<typename T_Scalar>
427  inline Matrix2<T_Scalar> operator*(T_Scalar d, const Matrix2<T_Scalar>& m)
428  {
429  return m * d;
430  }
431  //-----------------------------------------------------------------------------
432  // post multiplication: matrix * column vector
433  template<typename T_Scalar>
435  {
437  t.x() = v.x()*m.e(0,0) + v.y()*m.e(0,1);
438  t.y() = v.x()*m.e(1,0) + v.y()*m.e(1,1);
439  return t;
440  }
441  //-----------------------------------------------------------------------------
442  // pre-multiplication: row vector * matrix
443  template<typename T_Scalar>
445  {
447  t.x() = v.x()*m.e(0,0) + v.y()*m.e(1,0);
448  t.y() = v.x()*m.e(0,1) + v.y()*m.e(1,1);
449  return t;
450  }
451  //-----------------------------------------------------------------------------
452 
461 
462  #if VL_PIPELINE_PRECISION == 2
463  typedef dmat2 mat2;
465  #else
466  typedef fmat2 mat2;
468  #endif
469 }
470 
471 #endif
bool operator!=(const Matrix2 &m) const
Definition: Matrix2.hpp:103
T_Scalar diff(const Matrix2 &other) const
Definition: Matrix2.hpp:86
Matrix2 operator/(T_Scalar d) const
Definition: Matrix2.hpp:213
Matrix2< double > dmat2
A 2x2 matrix using double precision.
Definition: Matrix2.hpp:454
Matrix2 & setNull()
Definition: Matrix2.hpp:289
bool isNull() const
Definition: Matrix2.hpp:280
static Matrix2 & getNull(Matrix2 &out)
Definition: Matrix2.hpp:295
Matrix2(const Matrix2< T > &m)
Definition: Matrix2.hpp:55
T_Scalar * ptr()
Definition: Matrix2.hpp:238
Matrix2 & operator*=(T_Scalar d)
Definition: Matrix2.hpp:205
static Matrix2 & multiply(Matrix2 &out, const Matrix2 &p, const Matrix2 &q)
Definition: Matrix2.hpp:372
Matrix2 operator+(const Matrix2 &m) const
Definition: Matrix2.hpp:114
Matrix2 & invert(T_Scalar *determinant=NULL)
Definition: Matrix2.hpp:364
Matrix2 & operator/=(T_Scalar d)
Definition: Matrix2.hpp:223
The Matrix2 class is a template class that implements a generic 2x2 matrix, see also vl::dmat2...
Definition: Matrix2.hpp:49
Matrix2 & operator+=(T_Scalar d)
Definition: Matrix2.hpp:171
Matrix2 operator+(T_Scalar d) const
Definition: Matrix2.hpp:162
bool isIdentity() const
Definition: Matrix2.hpp:232
Matrix2 & setIdentity()
Definition: Matrix2.hpp:306
Matrix2 & operator=(const Matrix2 &m)
Definition: Matrix2.hpp:108
Matrix2 operator-(const Matrix2 &m) const
Definition: Matrix2.hpp:131
Matrix2< int > imat2
A 2x2 matrix using int precision.
Definition: Matrix2.hpp:458
Vector2< T_Scalar > mVec[2]
Definition: Matrix2.hpp:406
Visualization Library main namespace.
Matrix2 & operator-=(const Matrix2 &m)
Definition: Matrix2.hpp:140
Matrix2 & operator-=(T_Scalar d)
Definition: Matrix2.hpp:188
const T_Scalar * ptr() const
Definition: Matrix2.hpp:243
Matrix2< unsigned int > umat2
A 2x2 matrix using unsigned int precision.
Definition: Matrix2.hpp:460
Matrix2 operator*(T_Scalar d) const
Definition: Matrix2.hpp:196
Matrix2< float > fmat2
A 2x2 matrix using float precision.
Definition: Matrix2.hpp:456
Matrix2 & transpose()
Definition: Matrix2.hpp:248
Matrix2(T_Scalar e00, T_Scalar e01, T_Scalar e10, T_Scalar e11)
Definition: Matrix2.hpp:72
fmat2 mat2
Defined as: &#39;typedef fmat2 mat2&#39;. See also VL_PIPELINE_PRECISION.
Definition: Matrix2.hpp:467
Matrix2 & preMultiply(const Matrix2 &m)
Definition: Matrix2.hpp:391
Matrix2 & fill(T_Scalar val)
Definition: Matrix2.hpp:79
const T_Scalar & e(int i, int j) const
Definition: Matrix2.hpp:398
bool operator==(const Matrix2 &m) const
Definition: Matrix2.hpp:98
Matrix2 getInverse(T_Scalar *determinant=NULL) const
Definition: Matrix2.hpp:355
T_Scalar & e(int i, int j)
Definition: Matrix2.hpp:399
#define NULL
Definition: OpenGLDefs.hpp:81
T_Scalar getInverse(Matrix2 &dest) const
Definition: Matrix2.hpp:328
static Matrix2 getIdentity()
Definition: Matrix2.hpp:317
Matrix2 & getTransposed(Matrix2 &dest) const
Definition: Matrix2.hpp:272
The Vector2 class is a template class that implements a generic 2 components vector, see also vl::fvec2, vl::dvec2, vl::uvec2, vl::ivec2, vl::svec2, vl::usvec2, vl::bvec2, vl::ubvec2.
Definition: Vector2.hpp:97
Matrix2(T_Scalar n)
Definition: Matrix2.hpp:66
Matrix2 operator-() const
Definition: Matrix2.hpp:153
Matrix2 & operator*=(const Matrix2 &m)
Definition: Matrix2.hpp:148
const T_Scalar & x() const
Definition: Vector2.hpp:132
static Matrix2 getNull()
Definition: Matrix2.hpp:301
Matrix2 operator-(T_Scalar d) const
Definition: Matrix2.hpp:179
Matrix2 & postMultiply(const Matrix2 &m)
Definition: Matrix2.hpp:385
const T_Scalar & y() const
Definition: Vector2.hpp:133
#define VL_CHECK(expr)
Definition: checks.hpp:73
Matrix2 & operator+=(const Matrix2 &m)
Definition: Matrix2.hpp:123
T_Scalar scalar_type
Definition: Matrix2.hpp:52
Matrix2 getTransposed() const
Definition: Matrix2.hpp:263
static Matrix2 & getIdentity(Matrix2 &out)
Definition: Matrix2.hpp:322