1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 Author: Tony Peden, Jon Berndt, Mathias Frolich
6 Purpose: FGMatrix33 class
9 ------------- Copyright (C) 1998 by the authors above -------------
11 This program is free software; you can redistribute it and/or modify it under
12 the terms of the GNU Lesser General Public License as published by the Free Software
13 Foundation; either version 2 of the License, or (at your option) any later
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
21 You should have received a copy of the GNU Lesser General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
23 Place - Suite 330, Boston, MA 02111-1307, USA.
25 Further information about the GNU Lesser General Public License can also be found on
26 the world wide web at http://www.gnu.org.
28 FUNCTIONAL DESCRIPTION
29 --------------------------------------------------------------------------------
32 --------------------------------------------------------------------------------
34 03/16/2000 JSB Added exception throwing
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
38 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
40 #include "FGMatrix33.h"
41 #include "FGColumnVector3.h"
51 static const char *IdSrc = "$Id: FGMatrix33.cpp,v 1.11 2010/12/07 12:57:14 jberndt Exp $";
52 static const char *IdHdr = ID_MATRIX33;
54 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
58 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
60 FGMatrix33::FGMatrix33(void)
62 data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
63 data[6] = data[7] = data[8] = 0.0;
66 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
68 string FGMatrix33::Dump(const string& delimiter) const
71 buffer << setw(12) << setprecision(10) << data[0] << delimiter;
72 buffer << setw(12) << setprecision(10) << data[3] << delimiter;
73 buffer << setw(12) << setprecision(10) << data[6] << delimiter;
74 buffer << setw(12) << setprecision(10) << data[1] << delimiter;
75 buffer << setw(12) << setprecision(10) << data[4] << delimiter;
76 buffer << setw(12) << setprecision(10) << data[7] << delimiter;
77 buffer << setw(12) << setprecision(10) << data[2] << delimiter;
78 buffer << setw(12) << setprecision(10) << data[5] << delimiter;
79 buffer << setw(12) << setprecision(10) << data[8];
83 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85 string FGMatrix33::Dump(const string& delimiter, const string& prefix) const
89 buffer << prefix << right << fixed << setw(9) << setprecision(6) << data[0] << delimiter;
90 buffer << right << fixed << setw(9) << setprecision(6) << data[3] << delimiter;
91 buffer << right << fixed << setw(9) << setprecision(6) << data[6] << endl;
93 buffer << prefix << right << fixed << setw(9) << setprecision(6) << data[1] << delimiter;
94 buffer << right << fixed << setw(9) << setprecision(6) << data[4] << delimiter;
95 buffer << right << fixed << setw(9) << setprecision(6) << data[7] << endl;
97 buffer << prefix << right << fixed << setw(9) << setprecision(6) << data[2] << delimiter;
98 buffer << right << fixed << setw(9) << setprecision(6) << data[5] << delimiter;
99 buffer << right << fixed << setw(9) << setprecision(6) << data[8];
101 buffer << setw(0) << left;
106 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108 FGQuaternion FGMatrix33::GetQuaternion(void)
115 tempQ[0] = 1.0 + data[0] + data[4] + data[8];
116 tempQ[1] = 1.0 + data[0] - data[4] - data[8];
117 tempQ[2] = 1.0 - data[0] + data[4] - data[8];
118 tempQ[3] = 1.0 - data[0] - data[4] + data[8];
120 // Find largest of the above
122 for (int i=1; i<4; i++) if (tempQ[i] > tempQ[idx]) idx = i;
126 Q(1) = 0.50*sqrt(tempQ[0]);
127 Q(2) = 0.25*(data[7] - data[5])/Q(1);
128 Q(3) = 0.25*(data[2] - data[6])/Q(1);
129 Q(4) = 0.25*(data[3] - data[1])/Q(1);
132 Q(2) = 0.50*sqrt(tempQ[1]);
133 Q(1) = 0.25*(data[7] - data[5])/Q(2);
134 Q(3) = 0.25*(data[3] + data[1])/Q(2);
135 Q(4) = 0.25*(data[2] + data[6])/Q(2);
138 Q(3) = 0.50*sqrt(tempQ[2]);
139 Q(1) = 0.25*(data[2] - data[6])/Q(3);
140 Q(2) = 0.25*(data[3] + data[1])/Q(3);
141 Q(4) = 0.25*(data[7] + data[5])/Q(3);
144 Q(4) = 0.50*sqrt(tempQ[3]);
145 Q(1) = 0.25*(data[3] - data[1])/Q(4);
146 Q(2) = 0.25*(data[6] + data[2])/Q(4);
147 Q(3) = 0.25*(data[7] + data[5])/Q(4);
157 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159 ostream& operator<<(ostream& os, const FGMatrix33& M)
161 for (unsigned int i=1; i<=M.Rows(); i++) {
162 for (unsigned int j=1; j<=M.Cols(); j++) {
163 if (i == M.Rows() && j == M.Cols())
166 os << M(i,j) << ", ";
172 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174 istream& operator>>(istream& is, FGMatrix33& M)
176 for (unsigned int i=1; i<=M.Rows(); i++) {
177 for (unsigned int j=1; j<=M.Cols(); j++) {
184 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 double FGMatrix33::Determinant(void) const {
187 return data[0]*data[4]*data[8] + data[3]*data[7]*data[2]
188 + data[6]*data[1]*data[5] - data[6]*data[4]*data[2]
189 - data[3]*data[1]*data[8] - data[7]*data[5]*data[0];
192 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194 FGMatrix33 FGMatrix33::Inverse(void) const {
195 // Compute the inverse of a general matrix using Cramers rule.
196 // I guess googling for cramers rule gives tons of references
199 if (Determinant() != 0.0) {
200 double rdet = 1.0/Determinant();
202 double i11 = rdet*(data[4]*data[8]-data[7]*data[5]);
203 double i21 = rdet*(data[7]*data[2]-data[1]*data[8]);
204 double i31 = rdet*(data[1]*data[5]-data[4]*data[2]);
205 double i12 = rdet*(data[6]*data[5]-data[3]*data[8]);
206 double i22 = rdet*(data[0]*data[8]-data[6]*data[2]);
207 double i32 = rdet*(data[3]*data[2]-data[0]*data[5]);
208 double i13 = rdet*(data[3]*data[7]-data[6]*data[4]);
209 double i23 = rdet*(data[6]*data[1]-data[0]*data[7]);
210 double i33 = rdet*(data[0]*data[4]-data[3]*data[1]);
212 return FGMatrix33( i11, i12, i13,
216 return FGMatrix33( 0, 0, 0,
222 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
224 void FGMatrix33::InitMatrix(void)
226 data[0] = data[1] = data[2] = data[3] = data[4] = data[5] =
227 data[6] = data[7] = data[8] = 0.0;
230 // *****************************************************************************
231 // binary operators ************************************************************
232 // *****************************************************************************
234 FGMatrix33 FGMatrix33::operator-(const FGMatrix33& M) const
236 return FGMatrix33( data[0] - M.data[0],
244 data[8] - M.data[8] );
247 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 FGMatrix33& FGMatrix33::operator-=(const FGMatrix33 &M)
251 data[0] -= M.data[0];
252 data[1] -= M.data[1];
253 data[2] -= M.data[2];
254 data[3] -= M.data[3];
255 data[4] -= M.data[4];
256 data[5] -= M.data[5];
257 data[6] -= M.data[6];
258 data[7] -= M.data[7];
259 data[8] -= M.data[8];
264 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
266 FGMatrix33 FGMatrix33::operator+(const FGMatrix33& M) const
268 return FGMatrix33( data[0] + M.data[0],
276 data[8] + M.data[8] );
279 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
281 FGMatrix33& FGMatrix33::operator+=(const FGMatrix33 &M)
283 data[0] += M.data[0];
284 data[3] += M.data[3];
285 data[6] += M.data[6];
286 data[1] += M.data[1];
287 data[4] += M.data[4];
288 data[7] += M.data[7];
289 data[2] += M.data[2];
290 data[5] += M.data[5];
291 data[8] += M.data[8];
296 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298 FGMatrix33 FGMatrix33::operator*(const double scalar) const
300 return FGMatrix33( scalar * data[0],
311 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
313 FGMatrix33 operator*(double scalar, FGMatrix33 &M)
315 return FGMatrix33( scalar * M(1,1),
326 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
328 FGMatrix33& FGMatrix33::operator*=(const double scalar)
343 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
345 FGMatrix33 FGMatrix33::operator*(const FGMatrix33& M) const
349 Product.data[0] = data[0]*M.data[0] + data[3]*M.data[1] + data[6]*M.data[2];
350 Product.data[3] = data[0]*M.data[3] + data[3]*M.data[4] + data[6]*M.data[5];
351 Product.data[6] = data[0]*M.data[6] + data[3]*M.data[7] + data[6]*M.data[8];
352 Product.data[1] = data[1]*M.data[0] + data[4]*M.data[1] + data[7]*M.data[2];
353 Product.data[4] = data[1]*M.data[3] + data[4]*M.data[4] + data[7]*M.data[5];
354 Product.data[7] = data[1]*M.data[6] + data[4]*M.data[7] + data[7]*M.data[8];
355 Product.data[2] = data[2]*M.data[0] + data[5]*M.data[1] + data[8]*M.data[2];
356 Product.data[5] = data[2]*M.data[3] + data[5]*M.data[4] + data[8]*M.data[5];
357 Product.data[8] = data[2]*M.data[6] + data[5]*M.data[7] + data[8]*M.data[8];
362 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364 FGMatrix33& FGMatrix33::operator*=(const FGMatrix33& M)
366 // FIXME: Make compiler friendlier
369 a = data[0]; b=data[3]; c=data[6];
370 data[0] = a*M.data[0] + b*M.data[1] + c*M.data[2];
371 data[3] = a*M.data[3] + b*M.data[4] + c*M.data[5];
372 data[6] = a*M.data[6] + b*M.data[7] + c*M.data[8];
374 a = data[1]; b=data[4]; c=data[7];
375 data[1] = a*M.data[0] + b*M.data[1] + c*M.data[2];
376 data[4] = a*M.data[3] + b*M.data[4] + c*M.data[5];
377 data[7] = a*M.data[6] + b*M.data[7] + c*M.data[8];
379 a = data[2]; b=data[5]; c=data[8];
380 data[2] = a*M.data[0] + b*M.data[1] + c*M.data[2];
381 data[5] = a*M.data[3] + b*M.data[4] + c*M.data[5];
382 data[8] = a*M.data[6] + b*M.data[7] + c*M.data[8];
387 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 FGMatrix33 FGMatrix33::operator/(const double scalar) const
394 double tmp = 1.0/scalar;
395 Quot.data[0] = data[0] * tmp;
396 Quot.data[3] = data[3] * tmp;
397 Quot.data[6] = data[6] * tmp;
398 Quot.data[1] = data[1] * tmp;
399 Quot.data[4] = data[4] * tmp;
400 Quot.data[7] = data[7] * tmp;
401 Quot.data[2] = data[2] * tmp;
402 Quot.data[5] = data[5] * tmp;
403 Quot.data[8] = data[8] * tmp;
406 mE.Message = "Attempt to divide by zero in method FGMatrix33::operator/(const double scalar)";
412 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
414 FGMatrix33& FGMatrix33::operator/=(const double scalar)
417 double tmp = 1.0/scalar;
429 mE.Message = "Attempt to divide by zero in method FGMatrix33::operator/=(const double scalar)";
435 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
437 void FGMatrix33::T(void)
454 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456 FGColumnVector3 FGMatrix33::operator*(const FGColumnVector3& v) const
462 double tmp1 = v1*data[0]; //[(col-1)*eRows+row-1]
463 double tmp2 = v1*data[1];
464 double tmp3 = v1*data[2];
474 return FGColumnVector3( tmp1, tmp2, tmp3 );