Ignition Math

API Reference

4.0.0
Matrix3.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 #ifndef IGNITION_MATH_MATRIX3_HH_
18 #define IGNITION_MATH_MATRIX3_HH_
19 
20 #include <algorithm>
21 #include <cstring>
22 #include <ignition/math/Helpers.hh>
23 #include <ignition/math/Vector3.hh>
25 #include <ignition/math/config.hh>
26 
27 namespace ignition
28 {
29  namespace math
30  {
31  // Inline bracket to help doxygen filtering.
32  inline namespace IGNITION_MATH_VERSION_NAMESPACE {
33  //
34  template <typename T> class Quaternion;
35 
38  template<typename T>
39  class Matrix3
40  {
42  public: static const Matrix3<T> Identity;
43 
45  public: static const Matrix3<T> Zero;
46 
48  public: Matrix3()
49  {
50  std::memset(this->data, 0, sizeof(this->data[0][0])*9);
51  }
52 
55  public: Matrix3(const Matrix3<T> &_m)
56  {
57  std::memcpy(this->data, _m.data, sizeof(this->data[0][0])*9);
58  }
59 
70  public: Matrix3(T _v00, T _v01, T _v02,
71  T _v10, T _v11, T _v12,
72  T _v20, T _v21, T _v22)
73  {
74  this->data[0][0] = _v00;
75  this->data[0][1] = _v01;
76  this->data[0][2] = _v02;
77  this->data[1][0] = _v10;
78  this->data[1][1] = _v11;
79  this->data[1][2] = _v12;
80  this->data[2][0] = _v20;
81  this->data[2][1] = _v21;
82  this->data[2][2] = _v22;
83  }
84 
87  public: explicit Matrix3(const Quaternion<T> &_q)
88  {
89  Quaternion<T> qt = _q;
90  qt.Normalize();
91  this->Set(1 - 2*qt.Y()*qt.Y() - 2 *qt.Z()*qt.Z(),
92  2 * qt.X()*qt.Y() - 2*qt.Z()*qt.W(),
93  2 * qt.X() * qt.Z() + 2 * qt.Y() * qt.W(),
94  2 * qt.X() * qt.Y() + 2 * qt.Z() * qt.W(),
95  1 - 2*qt.X()*qt.X() - 2 * qt.Z()*qt.Z(),
96  2 * qt.Y() * qt.Z() - 2 * qt.X() * qt.W(),
97  2 * qt.X() * qt.Z() - 2 * qt.Y() * qt.W(),
98  2 * qt.Y() * qt.Z() + 2 * qt.X() * qt.W(),
99  1 - 2 * qt.X()*qt.X() - 2 * qt.Y()*qt.Y());
100  }
101 
103  public: virtual ~Matrix3() {}
104 
115  public: void Set(T _v00, T _v01, T _v02,
116  T _v10, T _v11, T _v12,
117  T _v20, T _v21, T _v22)
118  {
119  this->data[0][0] = _v00;
120  this->data[0][1] = _v01;
121  this->data[0][2] = _v02;
122  this->data[1][0] = _v10;
123  this->data[1][1] = _v11;
124  this->data[1][2] = _v12;
125  this->data[2][0] = _v20;
126  this->data[2][1] = _v21;
127  this->data[2][2] = _v22;
128  }
129 
134  public: void Axes(const Vector3<T> &_xAxis,
135  const Vector3<T> &_yAxis,
136  const Vector3<T> &_zAxis)
137  {
138  this->Col(0, _xAxis);
139  this->Col(1, _yAxis);
140  this->Col(2, _zAxis);
141  }
142 
146  public: void Axis(const Vector3<T> &_axis, T _angle)
147  {
148  T c = cos(_angle);
149  T s = sin(_angle);
150  T C = 1-c;
151 
152  this->data[0][0] = _axis.X()*_axis.X()*C + c;
153  this->data[0][1] = _axis.X()*_axis.Y()*C - _axis.Z()*s;
154  this->data[0][2] = _axis.X()*_axis.Z()*C + _axis.Y()*s;
155 
156  this->data[1][0] = _axis.Y()*_axis.X()*C + _axis.Z()*s;
157  this->data[1][1] = _axis.Y()*_axis.Y()*C + c;
158  this->data[1][2] = _axis.Y()*_axis.Z()*C - _axis.X()*s;
159 
160  this->data[2][0] = _axis.Z()*_axis.X()*C - _axis.Y()*s;
161  this->data[2][1] = _axis.Z()*_axis.Y()*C + _axis.X()*s;
162  this->data[2][2] = _axis.Z()*_axis.Z()*C + c;
163  }
164 
171  public: void From2Axes(const Vector3<T> &_v1, const Vector3<T> &_v2)
172  {
173  const T _v1LengthSquared = _v1.SquaredLength();
174  if (_v1LengthSquared <= 0.0)
175  {
176  // zero vector - we can't handle this
177  this->Set(1, 0, 0, 0, 1, 0, 0, 0, 1);
178  return;
179  }
180 
181  const T _v2LengthSquared = _v2.SquaredLength();
182  if (_v2LengthSquared <= 0.0)
183  {
184  // zero vector - we can't handle this
185  this->Set(1, 0, 0, 0, 1, 0, 0, 0, 1);
186  return;
187  }
188 
189  const T dot = _v1.Dot(_v2) / sqrt(_v1LengthSquared * _v2LengthSquared);
190  if (fabs(dot - 1.0) <= 1e-6)
191  {
192  // the vectors are parallel
193  this->Set(1, 0, 0, 0, 1, 0, 0, 0, 1);
194  return;
195  }
196  else if (fabs(dot + 1.0) <= 1e-6)
197  {
198  // the vectors are opposite
199  this->Set(-1, 0, 0, 0, -1, 0, 0, 0, -1);
200  return;
201  }
202 
203  const Vector3<T> cross = _v1.Cross(_v2).Normalize();
204 
205  this->Axis(cross, acos(dot));
206  }
207 
212  public: void Col(unsigned int _c, const Vector3<T> &_v)
213  {
214  unsigned int c = clamp(_c, 0u, 2u);
215 
216  this->data[0][c] = _v.X();
217  this->data[1][c] = _v.Y();
218  this->data[2][c] = _v.Z();
219  }
220 
224  public: Matrix3<T> &operator=(const Matrix3<T> &_mat)
225  {
226  memcpy(this->data, _mat.data, sizeof(this->data[0][0])*9);
227  return *this;
228  }
229 
231  public: Matrix3<T> operator-(const Matrix3<T> &_m) const
232  {
233  return Matrix3<T>(
234  this->data[0][0] - _m(0, 0),
235  this->data[0][1] - _m(0, 1),
236  this->data[0][2] - _m(0, 2),
237  this->data[1][0] - _m(1, 0),
238  this->data[1][1] - _m(1, 1),
239  this->data[1][2] - _m(1, 2),
240  this->data[2][0] - _m(2, 0),
241  this->data[2][1] - _m(2, 1),
242  this->data[2][2] - _m(2, 2));
243  }
244 
246  public: Matrix3<T> operator+(const Matrix3<T> &_m) const
247  {
248  return Matrix3<T>(
249  this->data[0][0]+_m(0, 0),
250  this->data[0][1]+_m(0, 1),
251  this->data[0][2]+_m(0, 2),
252  this->data[1][0]+_m(1, 0),
253  this->data[1][1]+_m(1, 1),
254  this->data[1][2]+_m(1, 2),
255  this->data[2][0]+_m(2, 0),
256  this->data[2][1]+_m(2, 1),
257  this->data[2][2]+_m(2, 2));
258  }
259 
261  public: Matrix3<T> operator*(const T &_s) const
262  {
263  return Matrix3<T>(
264  _s * this->data[0][0], _s * this->data[0][1], _s * this->data[0][2],
265  _s * this->data[1][0], _s * this->data[1][1], _s * this->data[1][2],
266  _s * this->data[2][0], _s * this->data[2][1], _s * this->data[2][2]);
267  }
268 
272  public: Matrix3<T> operator*(const Matrix3<T> &_m) const
273  {
274  return Matrix3<T>(
275  // first row
276  this->data[0][0]*_m(0, 0)+
277  this->data[0][1]*_m(1, 0)+
278  this->data[0][2]*_m(2, 0),
279 
280  this->data[0][0]*_m(0, 1)+
281  this->data[0][1]*_m(1, 1)+
282  this->data[0][2]*_m(2, 1),
283 
284  this->data[0][0]*_m(0, 2)+
285  this->data[0][1]*_m(1, 2)+
286  this->data[0][2]*_m(2, 2),
287 
288  // second row
289  this->data[1][0]*_m(0, 0)+
290  this->data[1][1]*_m(1, 0)+
291  this->data[1][2]*_m(2, 0),
292 
293  this->data[1][0]*_m(0, 1)+
294  this->data[1][1]*_m(1, 1)+
295  this->data[1][2]*_m(2, 1),
296 
297  this->data[1][0]*_m(0, 2)+
298  this->data[1][1]*_m(1, 2)+
299  this->data[1][2]*_m(2, 2),
300 
301  // third row
302  this->data[2][0]*_m(0, 0)+
303  this->data[2][1]*_m(1, 0)+
304  this->data[2][2]*_m(2, 0),
305 
306  this->data[2][0]*_m(0, 1)+
307  this->data[2][1]*_m(1, 1)+
308  this->data[2][2]*_m(2, 1),
309 
310  this->data[2][0]*_m(0, 2)+
311  this->data[2][1]*_m(1, 2)+
312  this->data[2][2]*_m(2, 2));
313  }
314 
319  public: Vector3<T> operator*(const Vector3<T> &_vec) const
320  {
321  return Vector3<T>(
322  this->data[0][0]*_vec.X() + this->data[0][1]*_vec.Y() +
323  this->data[0][2]*_vec.Z(),
324  this->data[1][0]*_vec.X() + this->data[1][1]*_vec.Y() +
325  this->data[1][2]*_vec.Z(),
326  this->data[2][0]*_vec.X() + this->data[2][1]*_vec.Y() +
327  this->data[2][2]*_vec.Z());
328  }
329 
334  public: friend inline Matrix3<T> operator*(T _s, const Matrix3<T> &_m)
335  {
336  return _m * _s;
337  }
338 
345  public: friend inline Vector3<T> operator*(const Vector3<T> &_v,
346  const Matrix3<T> &_m)
347  {
348  return Vector3<T>(
349  _m(0, 0)*_v.X() + _m(1, 0)*_v.Y() + _m(2, 0)*_v.Z(),
350  _m(0, 1)*_v.X() + _m(1, 1)*_v.Y() + _m(2, 1)*_v.Z(),
351  _m(0, 2)*_v.X() + _m(1, 2)*_v.Y() + _m(2, 2)*_v.Z());
352  }
353 
359  public: bool Equal(const Matrix3 &_m, const T &_tol) const
360  {
361  return equal<T>(this->data[0][0], _m(0, 0), _tol)
362  && equal<T>(this->data[0][1], _m(0, 1), _tol)
363  && equal<T>(this->data[0][2], _m(0, 2), _tol)
364  && equal<T>(this->data[1][0], _m(1, 0), _tol)
365  && equal<T>(this->data[1][1], _m(1, 1), _tol)
366  && equal<T>(this->data[1][2], _m(1, 2), _tol)
367  && equal<T>(this->data[2][0], _m(2, 0), _tol)
368  && equal<T>(this->data[2][1], _m(2, 1), _tol)
369  && equal<T>(this->data[2][2], _m(2, 2), _tol);
370  }
371 
375  public: bool operator==(const Matrix3<T> &_m) const
376  {
377  return this->Equal(_m, static_cast<T>(1e-6));
378  }
379 
383  public: Matrix3<T> &operator=(const Quaternion<T> &_q)
384  {
385  return *this = Matrix3<T>(_q);
386  }
387 
391  public: bool operator!=(const Matrix3<T> &_m) const
392  {
393  return !(*this == _m);
394  }
395 
400  public: inline const T &operator()(size_t _row, size_t _col) const
401  {
402  return this->data[clamp(_row, IGN_ZERO_SIZE_T, IGN_TWO_SIZE_T)]
404  }
405 
410  public: inline T &operator()(size_t _row, size_t _col)
411  {
412  return this->data[clamp(_row, IGN_ZERO_SIZE_T, IGN_TWO_SIZE_T)]
414  }
415 
418  public: T Determinant() const
419  {
420  T t0 = this->data[2][2]*this->data[1][1]
421  - this->data[2][1]*this->data[1][2];
422 
423  T t1 = -(this->data[2][2]*this->data[1][0]
424  -this->data[2][0]*this->data[1][2]);
425 
426  T t2 = this->data[2][1]*this->data[1][0]
427  - this->data[2][0]*this->data[1][1];
428 
429  return t0 * this->data[0][0]
430  + t1 * this->data[0][1]
431  + t2 * this->data[0][2];
432  }
433 
436  public: Matrix3<T> Inverse() const
437  {
438  T t0 = this->data[2][2]*this->data[1][1] -
439  this->data[2][1]*this->data[1][2];
440 
441  T t1 = -(this->data[2][2]*this->data[1][0] -
442  this->data[2][0]*this->data[1][2]);
443 
444  T t2 = this->data[2][1]*this->data[1][0] -
445  this->data[2][0]*this->data[1][1];
446 
447  T invDet = 1.0 / (t0 * this->data[0][0] +
448  t1 * this->data[0][1] +
449  t2 * this->data[0][2]);
450 
451  return invDet * Matrix3<T>(
452  t0,
453  - (this->data[2][2] * this->data[0][1] -
454  this->data[2][1] * this->data[0][2]),
455  + (this->data[1][2] * this->data[0][1] -
456  this->data[1][1] * this->data[0][2]),
457  t1,
458  + (this->data[2][2] * this->data[0][0] -
459  this->data[2][0] * this->data[0][2]),
460  - (this->data[1][2] * this->data[0][0] -
461  this->data[1][0] * this->data[0][2]),
462  t2,
463  - (this->data[2][1] * this->data[0][0] -
464  this->data[2][0] * this->data[0][1]),
465  + (this->data[1][1] * this->data[0][0] -
466  this->data[1][0] * this->data[0][1]));
467  }
468 
470  public: void Transpose()
471  {
472  std::swap(this->data[0][1], this->data[1][0]);
473  std::swap(this->data[0][2], this->data[2][0]);
474  std::swap(this->data[1][2], this->data[2][1]);
475  }
476 
479  public: Matrix3<T> Transposed() const
480  {
481  return Matrix3<T>(
482  this->data[0][0], this->data[1][0], this->data[2][0],
483  this->data[0][1], this->data[1][1], this->data[2][1],
484  this->data[0][2], this->data[1][2], this->data[2][2]);
485  }
486 
491  public: friend std::ostream &operator<<(
492  std::ostream &_out, const ignition::math::Matrix3<T> &_m)
493  {
494  _out << precision(_m(0, 0), 6) << " "
495  << precision(_m(0, 1), 6) << " "
496  << precision(_m(0, 2), 6) << " "
497  << precision(_m(1, 0), 6) << " "
498  << precision(_m(1, 1), 6) << " "
499  << precision(_m(1, 2), 6) << " "
500  << precision(_m(2, 0), 6) << " "
501  << precision(_m(2, 1), 6) << " "
502  << precision(_m(2, 2), 6);
503 
504  return _out;
505  }
510  public: friend std::istream &operator>>(
512  {
513  // Skip white spaces
514  _in.setf(std::ios_base::skipws);
515  T d[9];
516  _in >> d[0] >> d[1] >> d[2]
517  >> d[3] >> d[4] >> d[5]
518  >> d[6] >> d[7] >> d[8];
519 
520  _m.Set(d[0], d[1], d[2],
521  d[3], d[4], d[5],
522  d[6], d[7], d[8]);
523  return _in;
524  }
525 
527  private: T data[3][3];
528  };
529 
530  template<typename T>
532  1, 0, 0,
533  0, 1, 0,
534  0, 0, 1);
535 
536  template<typename T>
538  0, 0, 0,
539  0, 0, 0,
540  0, 0, 0);
541 
545  }
546  }
547 }
548 
549 #endif
friend std::istream & operator>>(std::istream &_in, Matrix3< T > &_m)
Stream extraction operator.
Definition: Matrix3.hh:510
T setf(T... args)
void Axes(const Vector3< T > &_xAxis, const Vector3< T > &_yAxis, const Vector3< T > &_zAxis)
Set the matrix from three axis (1 per column)
Definition: Matrix3.hh:134
const T & W() const
Get the w component.
Definition: Quaternion.hh:949
bool operator==(const Matrix3< T > &_m) const
Equality test operator.
Definition: Matrix3.hh:375
static const Matrix3< T > Identity
Identity matrix.
Definition: Matrix3.hh:42
const T & Z() const
Get the z component.
Definition: Quaternion.hh:970
T precision(const T &_a, const unsigned int &_precision)
get value at a specified precision
Definition: Helpers.hh:580
static const static double const static double const static double const static double const static float const static float const static float const static float const static uint16_t const static uint16_t const static uint16_t const static uint16_t const static int16_t const static int16_t const static int16_t const static int16_t const static uint32_t const static uint32_t const static uint32_t const static uint32_t const static int32_t const static int32_t const static int32_t const static int32_t const static uint64_t const static uint64_t const static uint64_t const static uint64_t const static int64_t const static int64_t const static int64_t const int64_t T clamp(T _v, T _min, T _max)
Simple clamping function.
Definition: Helpers.hh:396
T swap(T... args)
void Normalize()
Normalize the quaternion.
Definition: Quaternion.hh:224
void Col(unsigned int _c, const Vector3< T > &_v)
Set a column.
Definition: Matrix3.hh:212
Matrix3(T _v00, T _v01, T _v02, T _v10, T _v11, T _v12, T _v20, T _v21, T _v22)
Constructor.
Definition: Matrix3.hh:70
void Transpose()
Transpose this matrix.
Definition: Matrix3.hh:470
Matrix3(const Matrix3< T > &_m)
Copy constructor.
Definition: Matrix3.hh:55
friend Vector3< T > operator*(const Vector3< T > &_v, const Matrix3< T > &_m)
Matrix left multiplication operator for Vector3. Treats the Vector3 like a row vector multiplying the...
Definition: Matrix3.hh:345
Matrix3< double > Matrix3d
Definition: Matrix3.hh:543
Matrix3()
Constructor.
Definition: Matrix3.hh:48
T memset(T... args)
bool Equal(const Matrix3 &_m, const T &_tol) const
Equality test with tolerance.
Definition: Matrix3.hh:359
const T & X() const
Get the x component.
Definition: Quaternion.hh:956
const T & Y() const
Get the y component.
Definition: Quaternion.hh:963
STL class.
T X() const
Get the x value.
Definition: Vector3.hh:648
T Z() const
Get the z value.
Definition: Vector3.hh:662
Matrix3< T > operator*(const T &_s) const
returns the element wise scalar multiplication
Definition: Matrix3.hh:261
T Y() const
Get the y value.
Definition: Vector3.hh:655
friend Matrix3< T > operator*(T _s, const Matrix3< T > &_m)
Matrix multiplication operator for scaling.
Definition: Matrix3.hh:334
T memcpy(T... args)
bool operator!=(const Matrix3< T > &_m) const
Inequality test operator.
Definition: Matrix3.hh:391
A 3x3 matrix class.
Definition: Matrix3.hh:39
T Dot(const Vector3< T > &_v) const
Return the dot product of this vector and another vector.
Definition: Vector3.hh:199
Vector3 Cross(const Vector3< T > &_v) const
Return the cross product of this vector with another vector.
Definition: Vector3.hh:189
Matrix3< T > operator-(const Matrix3< T > &_m) const
returns the element wise difference of two matrices
Definition: Matrix3.hh:231
static const size_t IGN_ZERO_SIZE_T
size_t type with a value of 0
Definition: Helpers.hh:217
void From2Axes(const Vector3< T > &_v1, const Vector3< T > &_v2)
Set the matrix to represent rotation from vector _v1 to vector _v2, so that _v2.Normalize() == this *...
Definition: Matrix3.hh:171
void Set(T _v00, T _v01, T _v02, T _v10, T _v11, T _v12, T _v20, T _v21, T _v22)
Set values.
Definition: Matrix3.hh:115
Matrix3< T > operator*(const Matrix3< T > &_m) const
Matrix multiplication operator.
Definition: Matrix3.hh:272
Vector3< T > operator*(const Vector3< T > &_vec) const
Multiplication operator with Vector3 on the right treated like a column vector.
Definition: Matrix3.hh:319
Matrix3< int > Matrix3i
Definition: Matrix3.hh:542
friend std::ostream & operator<<(std::ostream &_out, const Matrix3< T > &_m)
Stream insertion operator.
Definition: Matrix3.hh:491
T SquaredLength() const
Return the square of the length (magnitude) of the vector.
Definition: Vector3.hh:124
const T & operator()(size_t _row, size_t _col) const
Array subscript operator.
Definition: Matrix3.hh:400
Matrix3< T > Inverse() const
Return the inverse matrix.
Definition: Matrix3.hh:436
The Vector3 class represents the generic vector containing 3 elements. Since it&#39;s commonly used to ke...
Definition: Vector3.hh:40
Matrix3(const Quaternion< T > &_q)
Construct Matrix3 from a quaternion.
Definition: Matrix3.hh:87
T Determinant() const
Return the determinant of the matrix.
Definition: Matrix3.hh:418
Matrix3< T > Transposed() const
Return the transpose of this matrix.
Definition: Matrix3.hh:479
static const size_t IGN_TWO_SIZE_T
size_t type with a value of 2
Definition: Helpers.hh:223
Matrix3< T > & operator=(const Matrix3< T > &_mat)
Equal operator. this = _mat.
Definition: Matrix3.hh:224
Definition: Angle.hh:39
static const Matrix3< T > Zero
Zero matrix.
Definition: Matrix3.hh:45
Matrix3< T > operator+(const Matrix3< T > &_m) const
returns the element wise sum of two matrices
Definition: Matrix3.hh:246
A quaternion class.
Definition: Matrix3.hh:34
Matrix3< T > & operator=(const Quaternion< T > &_q)
Set the matrix3 from a quaternion.
Definition: Matrix3.hh:383
Matrix3< float > Matrix3f
Definition: Matrix3.hh:544
STL class.
virtual ~Matrix3()
Desctructor.
Definition: Matrix3.hh:103
void Axis(const Vector3< T > &_axis, T _angle)
Set the matrix from an axis and angle.
Definition: Matrix3.hh:146
T & operator()(size_t _row, size_t _col)
Array subscript operator.
Definition: Matrix3.hh:410