KiCad PCB EDA Suite
matrix3x3.h
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KICAD, a free EDA CAD application.
3  *
4  * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
5  * Copyright (C) 2012-2021 Kicad Developers, see AUTHORS.txt for contributors.
6  *
7  * Matrix class (3x3)
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *-
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #ifndef MATRIX3X3_H_
28 #define MATRIX3X3_H_
29 
30 #include <math/vector2d.h>
31 
53 // Forward declaration for template friends
54 template <class T>
55 class MATRIX3x3;
56 
57 template <class T>
58 std::ostream& operator<<( std::ostream& aStream, const MATRIX3x3<T>& aMatrix );
59 
60 template <class T>
61 class MATRIX3x3
62 {
63 public:
64  T m_data[3][3];
65 
69  MATRIX3x3();
70 
84  MATRIX3x3( T a00, T a01, T a02, T a10, T a11, T a12, T a20, T a21, T a22 );
85 
91  void SetIdentity();
92 
98  void SetTranslation( VECTOR2<T> aTranslation );
99 
105  VECTOR2<T> GetTranslation() const;
106 
114  void SetRotation( T aAngle );
115 
121  void SetScale( VECTOR2<T> aScale );
122 
128  VECTOR2<T> GetScale() const;
129 
135  T Determinant() const;
136 
147  MATRIX3x3 Inverse() const;
148 
154  MATRIX3x3 Transpose() const;
155 
159  friend std::ostream& operator<<<T>( std::ostream& aStream, const MATRIX3x3<T>& aMatrix );
160 
161 };
162 
163 // Operators
164 
166 template <class T> MATRIX3x3<T> const operator*( MATRIX3x3<T> const& aA, MATRIX3x3<T> const& aB );
167 
169 template <class T> VECTOR2<T> const operator*( MATRIX3x3<T> const& aA, VECTOR2<T> const& aB );
170 
172 template <class T, class S> MATRIX3x3<T> const operator*( MATRIX3x3<T> const& aA, T aScalar );
173 template <class T, class S> MATRIX3x3<T> const operator*( T aScalar, MATRIX3x3<T> const& aMatrix );
174 
175 // ----------------------
176 // --- Implementation ---
177 // ----------------------
178 
179 template <class T>
181 {
182  for( int j = 0; j < 3; j++ )
183  {
184  for( int i = 0; i < 3; i++ )
185  {
186  m_data[i][j] = 0.0;
187  }
188  }
189 }
190 
191 
192 template <class T>
193 MATRIX3x3<T>::MATRIX3x3( T a00, T a01, T a02, T a10, T a11, T a12, T a20, T a21, T a22 )
194 {
195  m_data[0][0] = a00;
196  m_data[0][1] = a01;
197  m_data[0][2] = a02;
198 
199  m_data[1][0] = a10;
200  m_data[1][1] = a11;
201  m_data[1][2] = a12;
202 
203  m_data[2][0] = a20;
204  m_data[2][1] = a21;
205  m_data[2][2] = a22;
206 }
207 
208 
209 template <class T>
211 {
212  for( int j = 0; j < 3; j++ )
213  {
214  for( int i = 0; i < 3; i++ )
215  {
216  if( i == j )
217  m_data[i][j] = 1.0;
218  else
219  m_data[i][j] = 0.0;
220  }
221  }
222 }
223 
224 
225 template <class T>
227 {
228  m_data[0][2] = aTranslation.x;
229  m_data[1][2] = aTranslation.y;
230 }
231 
232 
233 template <class T>
235 {
236  VECTOR2<T> result;
237  result.x = m_data[0][2];
238  result.y = m_data[1][2];
239 
240  return result;
241 }
242 
243 
244 template <class T>
246 {
247  T cosValue = cos( aAngle );
248  T sinValue = sin( aAngle );
249  m_data[0][0] = cosValue;
250  m_data[0][1] = -sinValue;
251  m_data[1][0] = sinValue;
252  m_data[1][1] = cosValue;
253 }
254 
255 
256 template <class T>
258 {
259  m_data[0][0] = aScale.x;
260  m_data[1][1] = aScale.y;
261 }
262 
263 
264 template <class T>
266 {
267  VECTOR2<T> result( m_data[0][0], m_data[1][1] );
268 
269  return result;
270 }
271 
272 
273 template <class T>
274 MATRIX3x3<T> const operator*( MATRIX3x3<T> const& aA, MATRIX3x3<T> const& aB )
275 {
276  MATRIX3x3<T> result;
277 
278  for( int i = 0; i < 3; i++ )
279  {
280  for( int j = 0; j < 3; j++ )
281  {
282  result.m_data[i][j] = aA.m_data[i][0] * aB.m_data[0][j] +
283  aA.m_data[i][1] * aB.m_data[1][j] +
284  aA.m_data[i][2] * aB.m_data[2][j];
285  }
286  }
287 
288  return result;
289 }
290 
291 
292 template <class T>
293 VECTOR2<T> const operator*( MATRIX3x3<T> const& aMatrix, VECTOR2<T> const& aVector )
294 {
295  VECTOR2<T> result( 0, 0 );
296  result.x = aMatrix.m_data[0][0] * aVector.x + aMatrix.m_data[0][1] * aVector.y
297  + aMatrix.m_data[0][2];
298  result.y = aMatrix.m_data[1][0] * aVector.x + aMatrix.m_data[1][1] * aVector.y
299  + aMatrix.m_data[1][2];
300 
301  return result;
302 }
303 
304 
305 template <class T>
307 {
308  return m_data[0][0] * ( m_data[1][1] * m_data[2][2] - m_data[1][2] * m_data[2][1] )
309  - m_data[0][1] * ( m_data[1][0] * m_data[2][2] - m_data[1][2] * m_data[2][0] )
310  + m_data[0][2] * ( m_data[1][0] * m_data[2][1] - m_data[1][1] * m_data[2][0] );
311 }
312 
313 
314 template <class T, class S>
315 MATRIX3x3<T> const operator*( MATRIX3x3<T> const& aMatrix, S aScalar )
316 {
317  MATRIX3x3<T> result;
318 
319  for( int i = 0; i < 3; i++ )
320  {
321  for( int j = 0; j < 3; j++ )
322  {
323  result.m_data[i][j] = aMatrix.m_data[i][j] * aScalar;
324  }
325  }
326 
327  return result;
328 }
329 
330 
331 template <class T, class S>
332 MATRIX3x3<T> const operator*( S aScalar, MATRIX3x3<T> const& aMatrix )
333 {
334  return aMatrix * aScalar;
335 }
336 
337 
338 template <class T>
340 {
341  MATRIX3x3<T> result;
342 
343  result.m_data[0][0] = m_data[1][1] * m_data[2][2] - m_data[2][1] * m_data[1][2];
344  result.m_data[0][1] = m_data[0][2] * m_data[2][1] - m_data[2][2] * m_data[0][1];
345  result.m_data[0][2] = m_data[0][1] * m_data[1][2] - m_data[1][1] * m_data[0][2];
346 
347  result.m_data[1][0] = m_data[1][2] * m_data[2][0] - m_data[2][2] * m_data[1][0];
348  result.m_data[1][1] = m_data[0][0] * m_data[2][2] - m_data[2][0] * m_data[0][2];
349  result.m_data[1][2] = m_data[0][2] * m_data[1][0] - m_data[1][2] * m_data[0][0];
350 
351  result.m_data[2][0] = m_data[1][0] * m_data[2][1] - m_data[2][0] * m_data[1][1];
352  result.m_data[2][1] = m_data[0][1] * m_data[2][0] - m_data[2][1] * m_data[0][0];
353  result.m_data[2][2] = m_data[0][0] * m_data[1][1] - m_data[1][0] * m_data[0][1];
354 
355  return result * ( 1.0 / Determinant() );
356 }
357 
358 
359 template <class T>
361 {
362  MATRIX3x3<T> result;
363 
364  for( int i = 0; i < 3; i++ )
365  {
366  for( int j = 0; j < 3; j++ )
367  {
368  result.m_data[j][i] = m_data[i][j];
369  }
370  }
371 
372  return result;
373 }
374 
375 
376 template <class T>
377 std::ostream& operator<<( std::ostream& aStream, const MATRIX3x3<T>& aMatrix )
378 {
379  for( int i = 0; i < 3; i++ )
380  {
381  aStream << "| ";
382 
383  for( int j = 0; j < 3; j++ )
384  {
385  aStream << aMatrix.m_data[i][j];
386  aStream << " ";
387  }
388 
389  aStream << "|";
390  aStream << "\n";
391  }
392 
393  return aStream;
394 }
395 
396 
397 /* Default specializations */
399 
400 #endif /* MATRIX3X3_H_ */
void SetRotation(T aAngle)
Set the rotation components of the matrix.
Definition: matrix3x3.h:245
MATRIX3x3()
Initialize all matrix members to zero.
Definition: matrix3x3.h:180
MATRIX3x3 Inverse() const
Determine the inverse of the matrix.
Definition: matrix3x3.h:339
Define a general 2D-vector/point.
Definition: vector2d.h:61
MATRIX3x3 Transpose() const
Get the transpose of the matrix.
Definition: matrix3x3.h:360
void SetIdentity()
Set the matrix to the identity matrix.
Definition: matrix3x3.h:210
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:265
MATRIX3x3< double > MATRIX3x3D
Definition: matrix3x3.h:398
std::ostream & operator<<(std::ostream &aStream, const MATRIX3x3< T > &aMatrix)
Definition: matrix3x3.h:377
T m_data[3][3]
Definition: matrix3x3.h:64
MATRIX3x3< T > const operator *(MATRIX3x3< T > const &aA, MATRIX3x3< T > const &aB)
Matrix multiplication.
Definition: matrix3x3.h:274
VECTOR2< T > GetTranslation() const
Get the translation components of the matrix.
Definition: matrix3x3.h:234
void SetScale(VECTOR2< T > aScale)
Set the scale components of the matrix.
Definition: matrix3x3.h:257
T Determinant() const
Compute the determinant of the matrix.
Definition: matrix3x3.h:306
MATRIX3x3 describes a general 3x3 matrix.
Definition: matrix3x3.h:55
void SetTranslation(VECTOR2< T > aTranslation)
Set the translation components of the matrix.
Definition: matrix3x3.h:226