1 /********************************************************************************
2 * ReactPhysics3D physics library, http://www.reactphysics3d.com                 *
3 * Copyright (c) 2010-2020 Daniel Chappuis                                       *
4 *********************************************************************************
5 *                                                                               *
6 * This software is provided 'as-is', without any express or implied warranty.   *
7 * In no event will the authors be held liable for any damages arising from the  *
8 * use of this software.                                                         *
9 *                                                                               *
10 * Permission is granted to anyone to use this software for any purpose,         *
11 * including commercial applications, and to alter it and redistribute it        *
12 * freely, subject to the following restrictions:                                *
13 *                                                                               *
14 * 1. The origin of this software must not be misrepresented; you must not claim *
15 *    that you wrote the original software. If you use this software in a        *
16 *    product, an acknowledgment in the product documentation would be           *
17 *    appreciated but is not required.                                           *
18 *                                                                               *
19 * 2. Altered source versions must be plainly marked as such, and must not be    *
20 *    misrepresented as being the original software.                             *
21 *                                                                               *
22 * 3. This notice may not be removed or altered from any source distribution.    *
23 *                                                                               *
24 ********************************************************************************/
25 
26 #ifndef REACTPHYSICS3D_MATRIX2X2_H
27 #define REACTPHYSICS3D_MATRIX2X2_H
28 
29 // Libraries
30 #include <cassert>
31 #include <reactphysics3d/mathematics/Vector2.h>
32 
33 /// ReactPhysics3D namespace
34 namespace reactphysics3d {
35 
36 // Class Matrix2x2
37 /**
38  * This class represents a 2x2 matrix.
39  */
40 class Matrix2x2 {
41 
42     private :
43 
44         // -------------------- Attributes -------------------- //
45 
46         /// Rows of the matrix;
47         Vector2 mRows[2];
48 
49     public :
50 
51         // -------------------- Methods -------------------- //
52 
53         /// Constructor
54         Matrix2x2();
55 
56         /// Constructor
57         Matrix2x2(decimal value);
58 
59         /// Constructor
60         Matrix2x2(decimal a1, decimal a2, decimal b1, decimal b2);
61 
62         /// Destructor
63         ~Matrix2x2() = default;
64 
65         /// Copy-constructor
66         Matrix2x2(const Matrix2x2& matrix);
67 
68         /// Assignment operator
69         Matrix2x2& operator=(const Matrix2x2& matrix);
70 
71         /// Set all the values in the matrix
72         void setAllValues(decimal a1, decimal a2, decimal b1, decimal b2);
73 
74         /// Set the matrix to zero
75         void setToZero();
76 
77         /// Return a column
78         Vector2 getColumn(int i) const;
79 
80         /// Return a row
81         Vector2 getRow(int i) const;
82 
83         /// Return the transpose matrix
84         Matrix2x2 getTranspose() const;
85 
86         /// Return the determinant of the matrix
87         decimal getDeterminant() const;
88 
89         /// Return the trace of the matrix
90         decimal getTrace() const;
91 
92         /// Return the inverse matrix
93         Matrix2x2 getInverse() const;
94 
95         /// Return the matrix with absolute values
96         Matrix2x2 getAbsoluteMatrix() const;
97 
98         /// Set the matrix to the identity matrix
99         void setToIdentity();
100 
101         /// Return the 2x2 identity matrix
102         static Matrix2x2 identity();
103 
104         /// Return the 2x2 zero matrix
105         static Matrix2x2 zero();
106 
107         /// Overloaded operator for addition
108         friend Matrix2x2 operator+(const Matrix2x2& matrix1, const Matrix2x2& matrix2);
109 
110         /// Overloaded operator for substraction
111         friend Matrix2x2 operator-(const Matrix2x2& matrix1, const Matrix2x2& matrix2);
112 
113         /// Overloaded operator for the negative of the matrix
114         friend Matrix2x2 operator-(const Matrix2x2& matrix);
115 
116         /// Overloaded operator for multiplication with a number
117         friend Matrix2x2 operator*(decimal nb, const Matrix2x2& matrix);
118 
119         /// Overloaded operator for multiplication with a matrix
120         friend Matrix2x2 operator*(const Matrix2x2& matrix, decimal nb);
121 
122         /// Overloaded operator for matrix multiplication
123         friend Matrix2x2 operator*(const Matrix2x2& matrix1, const Matrix2x2& matrix2);
124 
125         /// Overloaded operator for multiplication with a vector
126         friend Vector2 operator*(const Matrix2x2& matrix, const Vector2& vector);
127 
128         /// Overloaded operator for equality condition
129         bool operator==(const Matrix2x2& matrix) const;
130 
131         /// Overloaded operator for the is different condition
132         bool operator!= (const Matrix2x2& matrix) const;
133 
134         /// Overloaded operator for addition with assignment
135         Matrix2x2& operator+=(const Matrix2x2& matrix);
136 
137         /// Overloaded operator for substraction with assignment
138         Matrix2x2& operator-=(const Matrix2x2& matrix);
139 
140         /// Overloaded operator for multiplication with a number with assignment
141         Matrix2x2& operator*=(decimal nb);
142 
143         /// Overloaded operator to read element of the matrix.
144         const Vector2& operator[](int row) const;
145 
146         /// Overloaded operator to read/write element of the matrix.
147         Vector2& operator[](int row);
148 
149         /// Return the string representation
150         std::string to_string() const;
151 };
152 
153 // Constructor of the class Matrix2x2
Matrix2x2()154 inline Matrix2x2::Matrix2x2() {
155 
156     // Initialize all values in the matrix to zero
157     setAllValues(0.0, 0.0, 0.0, 0.0);
158 }
159 
160 // Constructor
Matrix2x2(decimal value)161 inline Matrix2x2::Matrix2x2(decimal value) {
162     setAllValues(value, value, value, value);
163 }
164 
165 // Constructor with arguments
Matrix2x2(decimal a1,decimal a2,decimal b1,decimal b2)166 inline Matrix2x2::Matrix2x2(decimal a1, decimal a2, decimal b1, decimal b2) {
167 
168     // Initialize the matrix with the values
169     setAllValues(a1, a2, b1, b2);
170 }
171 
172 // Copy-constructor
Matrix2x2(const Matrix2x2 & matrix)173 inline Matrix2x2::Matrix2x2(const Matrix2x2& matrix) {
174     setAllValues(matrix.mRows[0][0], matrix.mRows[0][1],
175                  matrix.mRows[1][0], matrix.mRows[1][1]);
176 }
177 
178 // Method to set all the values in the matrix
setAllValues(decimal a1,decimal a2,decimal b1,decimal b2)179 inline void Matrix2x2::setAllValues(decimal a1, decimal a2,
180                                     decimal b1, decimal b2) {
181     mRows[0][0] = a1; mRows[0][1] = a2;
182     mRows[1][0] = b1; mRows[1][1] = b2;
183 }
184 
185 // Set the matrix to zero
setToZero()186 inline void Matrix2x2::setToZero() {
187     mRows[0].setToZero();
188     mRows[1].setToZero();
189 }
190 
191 // Return a column
getColumn(int i)192 inline Vector2 Matrix2x2::getColumn(int i) const {
193     assert(i>= 0 && i<2);
194     return Vector2(mRows[0][i], mRows[1][i]);
195 }
196 
197 // Return a row
getRow(int i)198 inline Vector2 Matrix2x2::getRow(int i) const {
199     assert(i>= 0 && i<2);
200     return mRows[i];
201 }
202 
203 // Return the transpose matrix
getTranspose()204 inline Matrix2x2 Matrix2x2::getTranspose() const {
205 
206     // Return the transpose matrix
207     return Matrix2x2(mRows[0][0], mRows[1][0],
208                      mRows[0][1], mRows[1][1]);
209 }
210 
211 // Return the determinant of the matrix
getDeterminant()212 inline decimal Matrix2x2::getDeterminant() const {
213 
214     // Compute and return the determinant of the matrix
215     return mRows[0][0] * mRows[1][1] - mRows[1][0] * mRows[0][1];
216 }
217 
218 // Return the trace of the matrix
getTrace()219 inline decimal Matrix2x2::getTrace() const {
220 
221     // Compute and return the trace
222     return (mRows[0][0] + mRows[1][1]);
223 }
224 
225 // Set the matrix to the identity matrix
setToIdentity()226 inline void Matrix2x2::setToIdentity() {
227     mRows[0][0] = 1.0; mRows[0][1] = 0.0;
228     mRows[1][0] = 0.0; mRows[1][1] = 1.0;
229 }
230 
231 // Return the 2x2 identity matrix
identity()232 inline Matrix2x2 Matrix2x2::identity() {
233 
234     // Return the isdentity matrix
235     return Matrix2x2(1.0, 0.0, 0.0, 1.0);
236 }
237 
238 // Return the 2x2 zero matrix
zero()239 inline Matrix2x2 Matrix2x2::zero() {
240     return Matrix2x2(0.0, 0.0, 0.0, 0.0);
241 }
242 
243 // Return the matrix with absolute values
getAbsoluteMatrix()244 inline Matrix2x2 Matrix2x2::getAbsoluteMatrix() const {
245     return Matrix2x2(fabs(mRows[0][0]), fabs(mRows[0][1]),
246                      fabs(mRows[1][0]), fabs(mRows[1][1]));
247 }
248 
249 // Overloaded operator for addition
250 inline Matrix2x2 operator+(const Matrix2x2& matrix1, const Matrix2x2& matrix2) {
251     return Matrix2x2(matrix1.mRows[0][0] + matrix2.mRows[0][0],
252                      matrix1.mRows[0][1] + matrix2.mRows[0][1],
253                      matrix1.mRows[1][0] + matrix2.mRows[1][0],
254                      matrix1.mRows[1][1] + matrix2.mRows[1][1]);
255 }
256 
257 // Overloaded operator for substraction
258 inline Matrix2x2 operator-(const Matrix2x2& matrix1, const Matrix2x2& matrix2) {
259     return Matrix2x2(matrix1.mRows[0][0] - matrix2.mRows[0][0],
260                      matrix1.mRows[0][1] - matrix2.mRows[0][1],
261                      matrix1.mRows[1][0] - matrix2.mRows[1][0],
262                      matrix1.mRows[1][1] - matrix2.mRows[1][1]);
263 }
264 
265 // Overloaded operator for the negative of the matrix
266 inline Matrix2x2 operator-(const Matrix2x2& matrix) {
267     return Matrix2x2(-matrix.mRows[0][0], -matrix.mRows[0][1],
268                      -matrix.mRows[1][0], -matrix.mRows[1][1]);
269 }
270 
271 // Overloaded operator for multiplication with a number
272 inline Matrix2x2 operator*(decimal nb, const Matrix2x2& matrix) {
273     return Matrix2x2(matrix.mRows[0][0] * nb, matrix.mRows[0][1] * nb,
274                      matrix.mRows[1][0] * nb, matrix.mRows[1][1] * nb);
275 }
276 
277 // Overloaded operator for multiplication with a matrix
278 inline Matrix2x2 operator*(const Matrix2x2& matrix, decimal nb) {
279     return nb * matrix;
280 }
281 
282 // Overloaded operator for matrix multiplication
283 inline Matrix2x2 operator*(const Matrix2x2& matrix1, const Matrix2x2& matrix2) {
284     return Matrix2x2(matrix1.mRows[0][0] * matrix2.mRows[0][0] + matrix1.mRows[0][1] *
285                      matrix2.mRows[1][0],
286                      matrix1.mRows[0][0] * matrix2.mRows[0][1] + matrix1.mRows[0][1] *
287                      matrix2.mRows[1][1],
288                      matrix1.mRows[1][0] * matrix2.mRows[0][0] + matrix1.mRows[1][1] *
289                      matrix2.mRows[1][0],
290                      matrix1.mRows[1][0] * matrix2.mRows[0][1] + matrix1.mRows[1][1] *
291                      matrix2.mRows[1][1]);
292 }
293 
294 // Overloaded operator for multiplication with a vector
295 inline Vector2 operator*(const Matrix2x2& matrix, const Vector2& vector) {
296     return Vector2(matrix.mRows[0][0]*vector.x + matrix.mRows[0][1]*vector.y,
297                    matrix.mRows[1][0]*vector.x + matrix.mRows[1][1]*vector.y);
298 }
299 
300 // Overloaded operator for equality condition
301 inline bool Matrix2x2::operator==(const Matrix2x2& matrix) const {
302     return (mRows[0][0] == matrix.mRows[0][0] && mRows[0][1] == matrix.mRows[0][1] &&
303             mRows[1][0] == matrix.mRows[1][0] && mRows[1][1] == matrix.mRows[1][1]);
304 }
305 
306 // Overloaded operator for the is different condition
307 inline bool Matrix2x2::operator!= (const Matrix2x2& matrix) const {
308     return !(*this == matrix);
309 }
310 
311 // Overloaded operator for addition with assignment
312 inline Matrix2x2& Matrix2x2::operator+=(const Matrix2x2& matrix) {
313    mRows[0][0] += matrix.mRows[0][0]; mRows[0][1] += matrix.mRows[0][1];
314    mRows[1][0] += matrix.mRows[1][0]; mRows[1][1] += matrix.mRows[1][1];
315    return *this;
316 }
317 
318 // Overloaded operator for substraction with assignment
319 inline Matrix2x2& Matrix2x2::operator-=(const Matrix2x2& matrix) {
320    mRows[0][0] -= matrix.mRows[0][0]; mRows[0][1] -= matrix.mRows[0][1];
321    mRows[1][0] -= matrix.mRows[1][0]; mRows[1][1] -= matrix.mRows[1][1];
322    return *this;
323 }
324 
325 // Overloaded operator for multiplication with a number with assignment
326 inline Matrix2x2& Matrix2x2::operator*=(decimal nb) {
327    mRows[0][0] *= nb; mRows[0][1] *= nb;
328    mRows[1][0] *= nb; mRows[1][1] *= nb;
329    return *this;
330 }
331 
332 // Overloaded operator to return a row of the matrix.
333 /// This operator is also used to access a matrix value using the syntax
334 /// matrix[row][col].
335 inline const Vector2& Matrix2x2::operator[](int row) const {
336     return mRows[row];
337 }
338 
339 // Overloaded operator to return a row of the matrix.
340 /// This operator is also used to access a matrix value using the syntax
341 /// matrix[row][col].
342 inline Vector2& Matrix2x2::operator[](int row) {
343     return mRows[row];
344 }
345 
346 // Get the string representation
to_string()347 inline std::string Matrix2x2::to_string() const {
348     return "Matrix2x2(" + std::to_string(mRows[0][0]) + "," + std::to_string(mRows[0][1]) + "," +
349            std::to_string(mRows[1][0]) + "," + std::to_string(mRows[1][1]) + ")";
350 }
351 
352 }
353 
354 #endif
355