Visualization Library 2.1.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  //-----------------------------------------------------------------------------
61  Matrix2(const Matrix2& other)
62  {
63  operator=(other);
64  }
65  //-----------------------------------------------------------------------------
67  {
68  setIdentity();
69  }
70  //-----------------------------------------------------------------------------
71  explicit Matrix2(T_Scalar n)
72  {
73  setIdentity();
74  e(0,0) = e(1,1) = n;
75  }
76  //-----------------------------------------------------------------------------
77  explicit Matrix2(T_Scalar e00, T_Scalar e01,
78  T_Scalar e10, T_Scalar e11 )
79  {
80  e(0,0) = e00; e(0,1) = e01;
81  e(1,0) = e10; e(1,1) = e11;
82  }
83  //-----------------------------------------------------------------------------
84  Matrix2& fill(T_Scalar val)
85  {
86  e(0,0) = e(1,0) =
87  e(0,1) = e(1,1) = val;
88  return *this;
89  }
90  //-----------------------------------------------------------------------------
91  T_Scalar diff(const Matrix2& other) const
92  {
93  T_Scalar err = 0;
94  for(int i=0; i<2; ++i)
95  for(int j=0; j<2; ++j)
96  if (e(j,i) > other.e(j,i)) // avoid fabs/abs
97  err += e(j,i) - other.e(j,i);
98  else
99  err += other.e(j,i) - e(j,i);
100  return err;
101  }
102  //-----------------------------------------------------------------------------
103  bool operator==(const Matrix2& m) const
104  {
105  return memcmp(m.mVec, mVec, sizeof(T_Scalar)*4) == 0;
106  }
107  //-----------------------------------------------------------------------------
108  bool operator!=(const Matrix2& m) const
109  {
110  return !operator==(m);
111  }
112  //-----------------------------------------------------------------------------
114  {
115  memcpy(mVec, m.mVec, sizeof(T_Scalar)*4);
116  return *this;
117  }
118  //-----------------------------------------------------------------------------
119  Matrix2 operator+(const Matrix2& m) const
120  {
121  Matrix2 t;
122  for(int i=0; i<2; ++i)
123  for(int j=0; j<2; ++j)
124  t.e(j,i) = e(j,i) + m.e(j,i);
125  return t;
126  }
127  //-----------------------------------------------------------------------------
129  {
130  for(int i=0; i<2; ++i)
131  for(int j=0; j<2; ++j)
132  e(j,i) += m.e(j,i);
133  return *this;
134  }
135  //-----------------------------------------------------------------------------
136  Matrix2 operator-(const Matrix2& m) const
137  {
138  Matrix2 t;
139  for(int i=0; i<2; ++i)
140  for(int j=0; j<2; ++j)
141  t.e(j,i) = e(j,i) - m.e(j,i);
142  return t;
143  }
144  //-----------------------------------------------------------------------------
146  {
147  for(int i=0; i<2; ++i)
148  for(int j=0; j<2; ++j)
149  e(j,i) -= m.e(j,i);
150  return *this;
151  }
152  //-----------------------------------------------------------------------------
154  {
155  return postMultiply(m);
156  }
157  //-----------------------------------------------------------------------------
159  {
160  Matrix2 t;
161  for(int i=0; i<2; ++i)
162  for(int j=0; j<2; ++j)
163  t.e(j,i) = -e(j,i);
164  return t;
165  }
166  //-----------------------------------------------------------------------------
167  Matrix2 operator+(T_Scalar d) const
168  {
169  Matrix2 t;
170  for(int i=0; i<2; ++i)
171  for(int j=0; j<2; ++j)
172  t.e(j,i) = e(j,i) + d;
173  return t;
174  }
175  //-----------------------------------------------------------------------------
176  Matrix2& operator+=(T_Scalar d)
177  {
178  for(int i=0; i<2; ++i)
179  for(int j=0; j<2; ++j)
180  e(j,i) += d;
181  return *this;
182  }
183  //-----------------------------------------------------------------------------
184  Matrix2 operator-(T_Scalar d) const
185  {
186  Matrix2 t;
187  for(int i=0; i<2; ++i)
188  for(int j=0; j<2; ++j)
189  t.e(j,i) = e(j,i) - d;
190  return t;
191  }
192  //-----------------------------------------------------------------------------
193  Matrix2& operator-=(T_Scalar d)
194  {
195  for(int i=0; i<2; ++i)
196  for(int j=0; j<2; ++j)
197  e(j,i) -= d;
198  return *this;
199  }
200  //-----------------------------------------------------------------------------
201  Matrix2 operator*(T_Scalar d) const
202  {
203  Matrix2 t;
204  for(int i=0; i<2; ++i)
205  for(int j=0; j<2; ++j)
206  t.e(j,i) = e(j,i) * d;
207  return t;
208  }
209  //-----------------------------------------------------------------------------
210  Matrix2& operator*=(T_Scalar d)
211  {
212  for(int i=0; i<2; ++i)
213  for(int j=0; j<2; ++j)
214  e(j,i) *= d;
215  return *this;
216  }
217  //-----------------------------------------------------------------------------
218  Matrix2 operator/(T_Scalar d) const
219  {
220  d = (T_Scalar)1 / d;
221  Matrix2 t;
222  for(int i=0; i<2; ++i)
223  for(int j=0; j<2; ++j)
224  t.e(j,i) = e(j,i) * d;
225  return t;
226  }
227  //-----------------------------------------------------------------------------
228  Matrix2& operator/=(T_Scalar d)
229  {
230  d = (T_Scalar)1 / d;
231  for(int i=0; i<2; ++i)
232  for(int j=0; j<2; ++j)
233  e(j,i) *= d;
234  return *this;
235  }
236  //-----------------------------------------------------------------------------
237  bool isIdentity() const
238  {
239  Matrix2 i;
240  return memcmp(ptr(), i.ptr(), sizeof(T_Scalar)*4) == 0;
241  }
242  //-----------------------------------------------------------------------------
243  T_Scalar* ptr()
244  {
245  return &e(0,0);
246  }
247  //-----------------------------------------------------------------------------
248  const T_Scalar* ptr() const
249  {
250  return &e(0,0);
251  }
252  //-----------------------------------------------------------------------------
254  {
255  T_Scalar tmp;
256  for(int i=0; i<2; ++i)
257  {
258  for(int j=i; j<2; ++j)
259  {
260  tmp = e(j,i);
261  e(j,i) = e(i,j);
262  e(i,j) = tmp;
263  }
264  }
265  return *this;
266  }
267  //-----------------------------------------------------------------------------
269  {
270  Matrix2 m;
271  for(int i=0; i<2; ++i)
272  for(int j=0; j<2; ++j)
273  m.e(j,i) = e(i,j);
274  return m;
275  }
276  //-----------------------------------------------------------------------------
278  {
279  for(int i=0; i<2; ++i)
280  for(int j=0; j<2; ++j)
281  dest.e(j,i) = e(i,j);
282  return dest;
283  }
284  //-----------------------------------------------------------------------------
285  bool isNull() const
286  {
287  for(int i=0; i<2; ++i)
288  for(int j=0; j<2; ++j)
289  if(mVec[j][i] != 0)
290  return false;
291  return true;
292  }
293  //-----------------------------------------------------------------------------
295  {
296  fill(0);
297  return *this;
298  }
299  //-----------------------------------------------------------------------------
300  static Matrix2& getNull(Matrix2& out)
301  {
302  out.fill(0);
303  return out;
304  }
305  //-----------------------------------------------------------------------------
306  static Matrix2 getNull()
307  {
308  return Matrix2().fill(0);
309  }
310  //-----------------------------------------------------------------------------
312  {
313  static const T_Scalar I2d[] =
314  {
315  (T_Scalar)1, (T_Scalar)0,
316  (T_Scalar)0, (T_Scalar)1
317  };
318  memcpy(mVec, I2d, sizeof(T_Scalar)*4);
319  return *this;
320  }
321  //-----------------------------------------------------------------------------
323  {
324  return Matrix2();
325  }
326  //-----------------------------------------------------------------------------
328  {
329  out.setIdentity();
330  return out;
331  }
332  //-----------------------------------------------------------------------------
333  T_Scalar getInverse(Matrix2& dest) const
334  {
335  if (&dest == this)
336  {
337  Matrix2 tmp;
338  T_Scalar det = getInverse(tmp);
339  dest = tmp;
340  return det;
341  }
342  else
343  {
344  const T_Scalar& a11 = e(0,0);
345  const T_Scalar& a12 = e(1,0);
346  const T_Scalar& a21 = e(0,1);
347  const T_Scalar& a22 = e(1,1);
348 
349  dest.fill(0);
350 
351  T_Scalar det = a11*a22-a12*a21;
352 
353  if (det != 0)
354  dest = Matrix2(+a22, -a12, -a21, +a11) / det;
355 
356  return det;
357  }
358  }
359  //-----------------------------------------------------------------------------
360  Matrix2 getInverse(T_Scalar *determinant=NULL) const
361  {
362  Matrix2 tmp;
363  T_Scalar det = getInverse(tmp);
364  if (determinant)
365  *determinant = det;
366  return tmp;
367  }
368  //-----------------------------------------------------------------------------
369  Matrix2& invert(T_Scalar *determinant=NULL)
370  {
371  T_Scalar det = getInverse(*this);
372  if (determinant)
373  *determinant = det;
374  return *this;
375  }
376  //-----------------------------------------------------------------------------
377  static Matrix2& multiply(Matrix2& out, const Matrix2& p, const Matrix2& q)
378  {
379  VL_CHECK(out.ptr() != p.ptr() && out.ptr() != q.ptr());
380 
381  out.e(0,0) = q.e(0,0)*p.e(0,0) + q.e(1,0)*p.e(0,1);
382  out.e(0,1) = q.e(0,1)*p.e(0,0) + q.e(1,1)*p.e(0,1);
383 
384  out.e(1,0) = q.e(0,0)*p.e(1,0) + q.e(1,0)*p.e(1,1);
385  out.e(1,1) = q.e(0,1)*p.e(1,0) + q.e(1,1)*p.e(1,1);
386 
387  return out;
388  }
389  //-----------------------------------------------------------------------------
391  {
393  return *this = multiply(t, *this, m);
394  }
395  //-----------------------------------------------------------------------------
397  {
399  return *this = multiply(t, m, *this);
400  }
401  //-----------------------------------------------------------------------------
402 
403  const T_Scalar& e(int i, int j) const { return mVec[j][i]; }
404  T_Scalar& e(int i, int j) { return mVec[j][i]; }
405 
406  private:
407  const Vector2<T_Scalar>& operator[](unsigned int i) const { VL_CHECK(i<2); return mVec[i]; }
408  Vector2<T_Scalar>& operator[](unsigned int i) { VL_CHECK(i<2); return mVec[i]; }
409 
410  protected:
412  };
413 
414  //-----------------------------------------------------------------------------
415  // OPERATORS
416  //-----------------------------------------------------------------------------
417  template<typename T_Scalar>
419  {
422  return t;
423  }
424  //-----------------------------------------------------------------------------
425  template<typename T_Scalar>
426  inline Matrix2<T_Scalar> operator+(T_Scalar d, const Matrix2<T_Scalar>& m)
427  {
428  return m + d;
429  }
430  //-----------------------------------------------------------------------------
431  template<typename T_Scalar>
432  inline Matrix2<T_Scalar> operator*(T_Scalar d, const Matrix2<T_Scalar>& m)
433  {
434  return m * d;
435  }
436  //-----------------------------------------------------------------------------
437  // post multiplication: matrix * column vector
438  template<typename T_Scalar>
440  {
442  t.x() = v.x()*m.e(0,0) + v.y()*m.e(0,1);
443  t.y() = v.x()*m.e(1,0) + v.y()*m.e(1,1);
444  return t;
445  }
446  //-----------------------------------------------------------------------------
447  // pre-multiplication: row vector * matrix
448  template<typename T_Scalar>
450  {
452  t.x() = v.x()*m.e(0,0) + v.y()*m.e(1,0);
453  t.y() = v.x()*m.e(0,1) + v.y()*m.e(1,1);
454  return t;
455  }
456  //-----------------------------------------------------------------------------
457 
466 
467  #if VL_PIPELINE_PRECISION == 2
468  typedef dmat2 mat2;
470  #else
471  typedef fmat2 mat2;
473  #endif
474 }
475 
476 #endif
bool operator!=(const Matrix2 &m) const
Definition: Matrix2.hpp:108
T_Scalar diff(const Matrix2 &other) const
Definition: Matrix2.hpp:91
Matrix2 operator/(T_Scalar d) const
Definition: Matrix2.hpp:218
Matrix2< double > dmat2
A 2x2 matrix using double precision.
Definition: Matrix2.hpp:459
Matrix2 & setNull()
Definition: Matrix2.hpp:294
bool isNull() const
Definition: Matrix2.hpp:285
static Matrix2 & getNull(Matrix2 &out)
Definition: Matrix2.hpp:300
Matrix2(const Matrix2< T > &m)
Definition: Matrix2.hpp:55
Matrix2(const Matrix2 &other)
Definition: Matrix2.hpp:61
T_Scalar * ptr()
Definition: Matrix2.hpp:243
Matrix2 & operator*=(T_Scalar d)
Definition: Matrix2.hpp:210
static Matrix2 & multiply(Matrix2 &out, const Matrix2 &p, const Matrix2 &q)
Definition: Matrix2.hpp:377
Matrix2 operator+(const Matrix2 &m) const
Definition: Matrix2.hpp:119
Matrix2 & invert(T_Scalar *determinant=NULL)
Definition: Matrix2.hpp:369
Matrix2 & operator/=(T_Scalar d)
Definition: Matrix2.hpp:228
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:176
Matrix2 operator+(T_Scalar d) const
Definition: Matrix2.hpp:167
bool isIdentity() const
Definition: Matrix2.hpp:237
Matrix2 & setIdentity()
Definition: Matrix2.hpp:311
Matrix2 & operator=(const Matrix2 &m)
Definition: Matrix2.hpp:113
Matrix2 operator-(const Matrix2 &m) const
Definition: Matrix2.hpp:136
Matrix2< int > imat2
A 2x2 matrix using int precision.
Definition: Matrix2.hpp:463
Vector2< T_Scalar > mVec[2]
Definition: Matrix2.hpp:411
Visualization Library main namespace.
Matrix2 & operator-=(const Matrix2 &m)
Definition: Matrix2.hpp:145
Matrix2 & operator-=(T_Scalar d)
Definition: Matrix2.hpp:193
const T_Scalar * ptr() const
Definition: Matrix2.hpp:248
Matrix2< unsigned int > umat2
A 2x2 matrix using unsigned int precision.
Definition: Matrix2.hpp:465
Matrix2 operator*(T_Scalar d) const
Definition: Matrix2.hpp:201
Matrix2< float > fmat2
A 2x2 matrix using float precision.
Definition: Matrix2.hpp:461
Matrix2 & transpose()
Definition: Matrix2.hpp:253
Matrix2(T_Scalar e00, T_Scalar e01, T_Scalar e10, T_Scalar e11)
Definition: Matrix2.hpp:77
fmat2 mat2
Defined as: &#39;typedef fmat2 mat2&#39;. See also VL_PIPELINE_PRECISION.
Definition: Matrix2.hpp:472
Matrix2 & preMultiply(const Matrix2 &m)
Definition: Matrix2.hpp:396
Matrix2 & fill(T_Scalar val)
Definition: Matrix2.hpp:84
const T_Scalar & e(int i, int j) const
Definition: Matrix2.hpp:403
bool operator==(const Matrix2 &m) const
Definition: Matrix2.hpp:103
Matrix2 getInverse(T_Scalar *determinant=NULL) const
Definition: Matrix2.hpp:360
T_Scalar & e(int i, int j)
Definition: Matrix2.hpp:404
#define NULL
Definition: OpenGLDefs.hpp:81
T_Scalar getInverse(Matrix2 &dest) const
Definition: Matrix2.hpp:333
static Matrix2 getIdentity()
Definition: Matrix2.hpp:322
Matrix2 & getTransposed(Matrix2 &dest) const
Definition: Matrix2.hpp:277
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:71
Matrix2 operator-() const
Definition: Matrix2.hpp:158
Matrix2 & operator*=(const Matrix2 &m)
Definition: Matrix2.hpp:153
const T_Scalar & x() const
Definition: Vector2.hpp:133
static Matrix2 getNull()
Definition: Matrix2.hpp:306
Matrix2 operator-(T_Scalar d) const
Definition: Matrix2.hpp:184
Matrix2 & postMultiply(const Matrix2 &m)
Definition: Matrix2.hpp:390
const T_Scalar & y() const
Definition: Vector2.hpp:134
#define VL_CHECK(expr)
Definition: checks.hpp:73
Matrix2 & operator+=(const Matrix2 &m)
Definition: Matrix2.hpp:128
T_Scalar scalar_type
Definition: Matrix2.hpp:52
Matrix2 getTransposed() const
Definition: Matrix2.hpp:268
static Matrix2 & getIdentity(Matrix2 &out)
Definition: Matrix2.hpp:327