1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 3 Header: FGMatrix33.h 4 Author: Tony Peden, Jon Berndt, Mathias Frolich 5 Date started: Unknown 6 7 ------------- Copyright (C) 2001 Jon S. Berndt (jon@jsbsim.org) ------------- 8 9 This program is free software; you can redistribute it and/or modify it under 10 the terms of the GNU Lesser General Public License as published by the Free Software 11 Foundation; either version 2 of the License, or (at your option) any later 12 version. 13 14 This program is distributed in the hope that it will be useful, but WITHOUT 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 17 details. 18 19 You should have received a copy of the GNU Lesser General Public License along with 20 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 21 Place - Suite 330, Boston, MA 02111-1307, USA. 22 23 Further information about the GNU Lesser General Public License can also be found on 24 the world wide web at http://www.gnu.org. 25 26 HISTORY 27 -------------------------------------------------------------------------------- 28 ??/??/?? TP Created 29 03/16/2000 JSB Added exception throwing 30 03/06/2004 MF Rework of the code to make it a bit compiler friendlier 31 32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 SENTRY 34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 35 36 #ifndef FGMATRIX33_H 37 #define FGMATRIX33_H 38 39 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 INCLUDES 41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 42 43 #include <string> 44 #include <iosfwd> 45 #include <stdexcept> 46 47 #include "FGColumnVector3.h" 48 49 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 50 FORWARD DECLARATIONS 51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 52 53 namespace JSBSim { 54 55 class FGColumnVector3; 56 class FGQuaternion; 57 58 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 59 CLASS DOCUMENTATION 60 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 61 62 /** Exception convenience class. 63 */ 64 65 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 DECLARATION: MatrixException 67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 68 69 // changed by James to inherit std::runtime_error, so that if this 70 // gets thrown, we can actually catch it. 71 class MatrixException : public std::runtime_error 72 { 73 public: MatrixException(const std::string & msg)74 MatrixException(const std::string& msg) : std::runtime_error{msg} { } 75 }; 76 77 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78 CLASS DOCUMENTATION 79 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 80 81 /** Handles matrix math operations. 82 @author Tony Peden, Jon Berndt, Mathias Froelich 83 */ 84 85 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 DECLARATION: FGMatrix33 87 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 88 89 class FGMatrix33 90 { 91 public: 92 93 enum { 94 eRows = 3, 95 eColumns = 3 96 }; 97 98 /** Default initializer. 99 100 Create a zero matrix. 101 */ 102 FGMatrix33(void); 103 104 /** Copy constructor. 105 106 @param M Matrix which is used for initialization. 107 108 Create copy of the matrix given in the argument. 109 */ FGMatrix33(const FGMatrix33 & M)110 FGMatrix33(const FGMatrix33& M) 111 { 112 data[0] = M.data[0]; 113 data[1] = M.data[1]; 114 data[2] = M.data[2]; 115 data[3] = M.data[3]; 116 data[4] = M.data[4]; 117 data[5] = M.data[5]; 118 data[6] = M.data[6]; 119 data[7] = M.data[7]; 120 data[8] = M.data[8]; 121 } 122 123 /** Initialization by given values. 124 125 @param m11 value of the 1,1 Matrix element. 126 @param m12 value of the 1,2 Matrix element. 127 @param m13 value of the 1,3 Matrix element. 128 @param m21 value of the 2,1 Matrix element. 129 @param m22 value of the 2,2 Matrix element. 130 @param m23 value of the 2,3 Matrix element. 131 @param m31 value of the 3,1 Matrix element. 132 @param m32 value of the 3,2 Matrix element. 133 @param m33 value of the 3,3 Matrix element. 134 135 Create a matrix from the doubles given in the arguments. 136 */ FGMatrix33(const double m11,const double m12,const double m13,const double m21,const double m22,const double m23,const double m31,const double m32,const double m33)137 FGMatrix33(const double m11, const double m12, const double m13, 138 const double m21, const double m22, const double m23, 139 const double m31, const double m32, const double m33) 140 { 141 data[0] = m11; 142 data[1] = m21; 143 data[2] = m31; 144 data[3] = m12; 145 data[4] = m22; 146 data[5] = m32; 147 data[6] = m13; 148 data[7] = m23; 149 data[8] = m33; 150 } 151 152 /** Destructor. 153 */ ~FGMatrix33(void)154 ~FGMatrix33(void) {} 155 156 /** Prints the contents of the matrix. 157 @param delimeter the item separator (tab or comma) 158 @return a string with the delimeter-separated contents of the matrix */ 159 std::string Dump(const std::string& delimeter) const; 160 161 /** Prints the contents of the matrix. 162 @param delimeter the item separator (tab or comma, etc.) 163 @param prefix an additional prefix that is used to indent the 3X3 matrix printout 164 @return a string with the delimeter-separated contents of the matrix */ 165 std::string Dump(const std::string& delimiter, const std::string& prefix) const; 166 167 /** Read access the entries of the matrix. 168 @param row Row index. 169 @param col Column index. 170 171 @return the value of the matrix entry at the given row and 172 column indices. Indices are counted starting with 1. 173 */ operator()174 double operator()(unsigned int row, unsigned int col) const { 175 return data[(col-1)*eRows+row-1]; 176 } 177 178 /** Write access the entries of the matrix. 179 Note that the indices given in the arguments are unchecked. 180 181 @param row Row index. 182 @param col Column index. 183 184 @return a reference to the matrix entry at the given row and 185 column indices. Indices are counted starting with 1. 186 */ operator()187 double& operator()(unsigned int row, unsigned int col) { 188 return data[(col-1)*eRows+row-1]; 189 } 190 191 /** Read access the entries of the matrix. 192 This function is just a shortcut for the <tt>double& 193 operator()(unsigned int row, unsigned int col)</tt> function. It is 194 used internally to access the elements in a more convenient way. 195 196 Note that the indices given in the arguments are unchecked. 197 198 @param row Row index. 199 @param col Column index. 200 201 @return the value of the matrix entry at the given row and 202 column indices. Indices are counted starting with 1. 203 */ Entry(unsigned int row,unsigned int col)204 double Entry(unsigned int row, unsigned int col) const { 205 return data[(col-1)*eRows+row-1]; 206 } 207 208 /** Write access the entries of the matrix. 209 This function is just a shortcut for the <tt>double& 210 operator()(unsigned int row, unsigned int col)</tt> function. It is 211 used internally to access the elements in a more convenient way. 212 213 Note that the indices given in the arguments are unchecked. 214 215 @param row Row index. 216 @param col Column index. 217 218 @return a reference to the matrix entry at the given row and 219 column indices. Indices are counted starting with 1. 220 */ Entry(unsigned int row,unsigned int col)221 double& Entry(unsigned int row, unsigned int col) { 222 return data[(col-1)*eRows+row-1]; 223 } 224 225 /** Number of rows in the matrix. 226 @return the number of rows in the matrix. 227 */ Rows(void)228 unsigned int Rows(void) const { return eRows; } 229 230 /** Number of cloumns in the matrix. 231 @return the number of columns in the matrix. 232 */ Cols(void)233 unsigned int Cols(void) const { return eColumns; } 234 235 /** Transposed matrix. 236 This function only returns the transpose of this matrix. This matrix itself 237 remains unchanged. 238 @return the transposed matrix. 239 */ Transposed(void)240 FGMatrix33 Transposed(void) const { 241 return FGMatrix33( data[0], data[1], data[2], 242 data[3], data[4], data[5], 243 data[6], data[7], data[8] ); 244 } 245 246 /** Transposes this matrix. 247 This function only transposes this matrix. Nothing is returned. 248 */ 249 void T(void); 250 251 /** Initialize the matrix. 252 This function initializes a matrix to all 0.0. 253 */ 254 void InitMatrix(void); 255 256 /** Initialize the matrix. 257 This function initializes a matrix to user specified values. 258 */ InitMatrix(const double m11,const double m12,const double m13,const double m21,const double m22,const double m23,const double m31,const double m32,const double m33)259 void InitMatrix(const double m11, const double m12, const double m13, 260 const double m21, const double m22, const double m23, 261 const double m31, const double m32, const double m33) 262 { 263 data[0] = m11; 264 data[1] = m21; 265 data[2] = m31; 266 data[3] = m12; 267 data[4] = m22; 268 data[5] = m32; 269 data[6] = m13; 270 data[7] = m23; 271 data[8] = m33; 272 } 273 274 /** Returns the quaternion associated with this direction cosine (rotation) matrix. 275 */ 276 FGQuaternion GetQuaternion(void) const; 277 278 /** Returns the Euler angle column vector associated with this matrix. 279 */ 280 FGColumnVector3 GetEuler() const; 281 282 /** Determinant of the matrix. 283 @return the determinant of the matrix. 284 */ 285 double Determinant(void) const; 286 287 /** Return if the matrix is invertible. 288 Checks and returns if the matrix is nonsingular and thus 289 invertible. This is done by simply computing the determinant and 290 check if it is zero. Note that this test does not cover any 291 instabilities caused by nearly singular matirces using finite 292 arithmetics. It only checks exact singularity. 293 */ Invertible(void)294 bool Invertible(void) const { return 0.0 != Determinant(); } 295 296 /** Return the inverse of the matrix. 297 Computes and returns if the inverse of the matrix. It is computed 298 by Cramers Rule. Also there are no checks performed if the matrix 299 is invertible. If you are not sure that it really is check this 300 with the @ref Invertible() call before. 301 */ 302 FGMatrix33 Inverse(void) const; 303 304 /** Assignment operator. 305 306 @param A source matrix. 307 308 Copy the content of the matrix given in the argument into *this. 309 */ 310 FGMatrix33& operator=(const FGMatrix33& A) 311 { 312 data[0] = A.data[0]; 313 data[1] = A.data[1]; 314 data[2] = A.data[2]; 315 data[3] = A.data[3]; 316 data[4] = A.data[4]; 317 data[5] = A.data[5]; 318 data[6] = A.data[6]; 319 data[7] = A.data[7]; 320 data[8] = A.data[8]; 321 return *this; 322 } 323 324 /** Matrix vector multiplication. 325 326 @param v vector to multiply with. 327 @return matric vector product. 328 329 Compute and return the product of the current matrix with the 330 vector given in the argument. 331 */ 332 FGColumnVector3 operator*(const FGColumnVector3& v) const; 333 334 /** Matrix subtraction. 335 336 @param B matrix to add to. 337 @return difference of the matrices. 338 339 Compute and return the sum of the current matrix and the matrix 340 B given in the argument. 341 */ 342 FGMatrix33 operator-(const FGMatrix33& B) const; 343 344 /** Matrix addition. 345 346 @param B matrix to add to. 347 @return sum of the matrices. 348 349 Compute and return the sum of the current matrix and the matrix 350 B given in the argument. 351 */ 352 FGMatrix33 operator+(const FGMatrix33& B) const; 353 354 /** Matrix product. 355 356 @param B matrix to add to. 357 @return product of the matrices. 358 359 Compute and return the product of the current matrix and the matrix 360 B given in the argument. 361 */ 362 FGMatrix33 operator*(const FGMatrix33& B) const; 363 364 /** Multiply the matrix with a scalar. 365 366 @param scalar scalar factor to multiply with. 367 @return scaled matrix. 368 369 Compute and return the product of the current matrix with the 370 scalar value scalar given in the argument. 371 */ 372 FGMatrix33 operator*(const double scalar) const; 373 374 /** Multiply the matrix with 1.0/scalar. 375 376 @param scalar scalar factor to divide through. 377 @return scaled matrix. 378 379 Compute and return the product of the current matrix with the 380 scalar value 1.0/scalar, where scalar is given in the argument. 381 */ 382 FGMatrix33 operator/(const double scalar) const; 383 384 /** In place matrix subtraction. 385 386 @param B matrix to subtract. 387 @return reference to the current matrix. 388 389 Compute the diffence from the current matrix and the matrix B 390 given in the argument. 391 */ 392 FGMatrix33& operator-=(const FGMatrix33 &B); 393 394 /** In place matrix addition. 395 396 @param B matrix to add. 397 @return reference to the current matrix. 398 399 Compute the sum of the current matrix and the matrix B 400 given in the argument. 401 */ 402 FGMatrix33& operator+=(const FGMatrix33 &B); 403 404 /** In place matrix multiplication. 405 406 @param B matrix to multiply with. 407 @return reference to the current matrix. 408 409 Compute the product of the current matrix and the matrix B 410 given in the argument. 411 */ 412 FGMatrix33& operator*=(const FGMatrix33 &B); 413 414 /** In place matrix scale. 415 416 @param scalar scalar value to multiply with. 417 @return reference to the current matrix. 418 419 Compute the product of the current matrix and the scalar value scalar 420 given in the argument. 421 */ 422 FGMatrix33& operator*=(const double scalar); 423 424 /** In place matrix scale. 425 426 @param scalar scalar value to divide through. 427 @return reference to the current matrix. 428 429 Compute the product of the current matrix and the scalar value 430 1.0/scalar, where scalar is given in the argument. 431 */ 432 FGMatrix33& operator/=(const double scalar); 433 434 private: 435 double data[eRows*eColumns]; 436 }; 437 438 /** Scalar multiplication. 439 440 @param scalar scalar value to multiply with. 441 @param A Matrix to multiply. 442 443 Multiply the Matrix with a scalar value. 444 */ 445 inline FGMatrix33 operator*(double scalar, const FGMatrix33& A) { 446 // use already defined operation. 447 return A*scalar; 448 } 449 450 /** Write matrix to a stream. 451 452 @param os Stream to write to. 453 @param M Matrix to write. 454 455 Write the matrix to a stream. 456 */ 457 std::ostream& operator<<(std::ostream& os, const FGMatrix33& M); 458 459 /** Read matrix from a stream. 460 461 @param os Stream to read from. 462 @param M Matrix to initialize with the values from the stream. 463 464 Read matrix from a stream. 465 */ 466 std::istream& operator>>(std::istream& is, FGMatrix33& M); 467 468 } // namespace JSBSim 469 #endif 470