OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimMatrix4x4.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Garrett Potts (gpotts@imagelinks.com)
6 //
7 // Description:
8 //
9 // Contains class declaration for locpt. This uses geotrans
10 // local cartesian implementation.
11 //*******************************************************************
12 // $Id: ossimMatrix4x4.cpp 11856 2007-10-12 15:21:17Z gpotts $
13 
15 #include <ossim/matrix/newmatap.h>
17 
18 ossimMatrix4x4::ossimMatrix4x4(const NEWMAT::Matrix& m)
19  :theData(4,4)
20 {
21  if((m.Nrows() == 4) &&
22  (m.Ncols() == 4))
23  {
24  theData = m;
25  }
26  else if((m.Nrows()==3)&&
27  (m.Ncols()==3))
28  {
29  theData[0][0] = m[0][0];
30  theData[0][1] = m[0][1];
31  theData[0][2] = m[0][2];
32  theData[0][3] = 0.0;
33  theData[1][0] = m[1][0];
34  theData[1][1] = m[1][1];
35  theData[1][2] = m[1][2];
36  theData[1][3] = 0.0;
37  theData[2][0] = m[2][0];
38  theData[2][1] = m[2][1];
39  theData[2][2] = m[2][2];
40  theData[2][3] = 0.0;
41  theData[3][0] = 0.0;
42  theData[3][1] = 0.0;
43  theData[3][2] = 0.0;
44  theData[3][3] = 1.0;
45  }
46  else
47  {
48  theData[0][0] = 1.0;
49  theData[0][1] = 0.0;
50  theData[0][2] = 0.0;
51  theData[0][3] = 0.0;
52 
53  theData[1][0] = 0.0;
54  theData[1][1] = 1.0;
55  theData[1][2] = 0.0;
56  theData[1][3] = 0.0;
57 
58  theData[2][0] = 0.0;
59  theData[2][1] = 0.0;
60  theData[2][2] = 1.0;
61  theData[2][3] = 0.0;
62 
63  theData[3][0] = 0.0;
64  theData[3][1] = 0.0;
65  theData[3][2] = 0.0;
66  theData[3][3] = 1.0;
67  }
68 }
69 
71  :theData(4, 4)
72 {
73  theData[0][0] = 1.0;
74  theData[0][1] = 0.0;
75  theData[0][2] = 0.0;
76  theData[0][3] = 0.0;
77 
78  theData[1][0] = 0.0;
79  theData[1][1] = 1.0;
80  theData[1][2] = 0.0;
81  theData[1][3] = 0.0;
82 
83  theData[2][0] = 0.0;
84  theData[2][1] = 0.0;
85  theData[2][2] = 1.0;
86  theData[2][3] = 0.0;
87 
88  theData[3][0] = 0.0;
89  theData[3][1] = 0.0;
90  theData[3][2] = 0.0;
91  theData[3][3] = 1.0;
92 }
93 
94 ossimMatrix4x4::ossimMatrix4x4(double v00, double v01, double v02, double v03,
95  double v10, double v11, double v12, double v13,
96  double v20, double v21, double v22, double v23,
97  double v30, double v31, double v32, double v33)
98  :theData(4, 4)
99 {
100  theData[0][0] = v00;
101  theData[0][1] = v01;
102  theData[0][2] = v02;
103  theData[0][3] = v03;
104 
105  theData[1][0] = v10;
106  theData[1][1] = v11;
107  theData[1][2] = v12;
108  theData[1][3] = v13;
109 
110  theData[2][0] = v20;
111  theData[2][1] = v21;
112  theData[2][2] = v22;
113  theData[2][3] = v23;
114 
115  theData[3][0] = v30;
116  theData[3][1] = v31;
117  theData[3][2] = v32;
118  theData[3][3] = v33;
119 }
120 #define QX q.theVector[0]
121 #define QY q.theVector[1]
122 #define QZ q.theVector[2]
123 #define QW q.theVector[3]
125 {
126  setIdentity();
127  setRotate(quat);
128 }
129 
131 {
132  ossim::Quaternion q(quat);
133  double length2 = q.length2();
134  if (length2!=1.0 && length2!=0)
135  {
136  // normalize quat if required.
137  q /= sqrt(length2);
138  }
139 
140  // Source: Gamasutra, Rotating Objects Using Quaternions
141  //
142  //http://www.gamasutra.com/features/19980703/quaternions_01.htm
143 
144  double wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
145 
146  // calculate coefficients
147  x2 = QX + QX;
148  y2 = QY + QY;
149  z2 = QZ + QZ;
150 
151  xx = QX * x2;
152  xy = QX * y2;
153  xz = QX * z2;
154 
155  yy = QY * y2;
156  yz = QY * z2;
157  zz = QZ * z2;
158 
159  wx = QW * x2;
160  wy = QW * y2;
161  wz = QW * z2;
162 
163  theData[0][0] = 1.0 - (yy + zz);
164  theData[0][1] = xy - wz;
165  theData[0][2] = xz + wy;
166 
167  theData[1][0] = xy + wz;
168  theData[1][1] = 1.0 - (xx + zz);
169  theData[1][2] = yz - wx;
170 
171  theData[2][0] = xz - wy;
172  theData[2][1] = yz + wx;
173  theData[2][2] = 1.0 - (xx + yy);
174 }
175 
177 {
178  ossim::Quaternion quat;
179 
180  getRotate(quat);
181 
182  return quat;
183 }
184 
186 {
187  ossim_float64 tr, s;
188  ossim_float64 tq[4];
189  int i, j, k;
190 
191  int nxt[3] = {1, 2, 0};
192 
193  tr = theData[0][0] + theData[1][1] + theData[2][2]+1.0;
194 
195  // check the diagonal
196  if (tr > 0.0)
197  {
198  s = (ossim_float64)std::sqrt (tr);
199  QW = s / 2.0;
200  s = 0.5 / s;
201  QX = (theData[2][1] - theData[1][2]) * s;
202  QY = (theData[0][2] - theData[2][0]) * s;
203  QZ = (theData[1][0] - theData[0][1]) * s;
204  }
205  else
206  {
207  // diagonal is negative
208  i = 0;
209  if (theData[1][1] > theData[0][0])
210  i = 1;
211  if (theData[2][2] > theData[i][i])
212  i = 2;
213  j = nxt[i];
214  k = nxt[j];
215 
216  s = (ossim_float64)std::sqrt((theData[i][i] - (theData[j][j] + theData[k][k])) + 1.0);
217 
218  tq[i] = s * 0.5;
219 
220  if (s != 0.0)
221  s = 0.5 / s;
222 
223  tq[3] = (theData[k][j] - theData[j][k]) * s;
224  tq[j] = (theData[j][i] + theData[i][j]) * s;
225  tq[k] = (theData[k][i] + theData[i][k]) * s;
226 
227  QX = tq[0];
228  QY = tq[1];
229  QZ = tq[2];
230  QW = tq[3];
231  }
232 }
233 
235 {
236  NEWMAT::DiagonalMatrix d;
237  NEWMAT::SymmetricMatrix s;
238 
239  s << theData;
240 
241  NEWMAT::EigenValues(s, d);
242 
243  return ossimColumnVector3d(d[0], d[1], d[2]);
244 }
245 
247 {
248  theData[0][0] = 0.0;
249  theData[0][1] = 0.0;
250  theData[0][2] = 0.0;
251  theData[0][3] = 0.0;
252 
253  theData[1][0] = 0.0;
254  theData[1][1] = 0.0;
255  theData[1][2] = 0.0;
256  theData[1][3] = 0.0;
257 
258  theData[2][0] = 0.0;
259  theData[2][1] = 0.0;
260  theData[2][2] = 0.0;
261  theData[2][3] = 0.0;
262 
263  theData[3][0] = 0.0;
264  theData[3][1] = 0.0;
265  theData[3][2] = 0.0;
266  theData[3][3] = 0.0;
267 }
268 
270 {
271  setZero();
272  theData[0][0] = 1.0;
273  theData[1][1] = 1.0;
274  theData[2][2] = 1.0;
275  theData[3][3] = 1.0;
276 }
277 
279 {
280  ossimMatrix4x4 m(1.0, 0.0, 0.0, 0.0,
281  0.0, 1.0, 0.0, 0.0,
282  0.0, 0.0, 1.0, 0.0,
283  0.0, 0.0, 0.0, 1.0);
284 
285  return m.getData();
286 }
287 
288 NEWMAT::Matrix ossimMatrix4x4::createRotateOnly(const ossimMatrix4x4 &aMatrix)
289 {
290  ossimMatrix4x4 m = aMatrix;
291 
292  m.theData[0][3] = 0;
293  m.theData[1][3] = 0;
294  m.theData[2][3] = 0;
295  m.theData[3][3] = 1.0;
296 
297  m.theData[3][0] = 0.0;
298  m.theData[3][1] = 0.0;
299  m.theData[3][2] = 0.0;
300  m.theData[3][3] = 1.0;
301 
302  return m.getData();
303 }
304 
306 {
307  ossimMatrix4x4 m;
308 
309  m.getData() = 0.0;
310 
311  return m.getData();
312 }
313 
315  double y,
316  double z)
317 {
318  ossimMatrix4x4 m(1.0, 0.0, 0.0, x,
319  0.0, 1.0, 0.0, y,
320  0.0, 0.0, 1.0, z,
321  0.0, 0.0, 0.0, 1.0);
322 
323  return m.getData();
324 }
325 
326 NEWMAT::Matrix ossimMatrix4x4::createRotationMatrix(double angleX,
327  double angleY,
328  double angleZ,
329  ossimCoordSysOrientMode orientationMode)
330 {
331  return (createRotationZMatrix(angleZ,
332  orientationMode)*
333  createRotationYMatrix(angleY,
334  orientationMode)*
335  createRotationXMatrix(angleX,
336  orientationMode));
337 }
338 
339 NEWMAT::Matrix ossimMatrix4x4::createRotationXMatrix(double angle,
340  ossimCoordSysOrientMode orientationMode)
341 {
342  NEWMAT::Matrix m(4,4);
343 
344  double Cosine = cos(angle*RAD_PER_DEG);
345  double Sine = sin(angle*RAD_PER_DEG);
346 
347  if(orientationMode == OSSIM_RIGHT_HANDED)
348  {
349  m << 1.0 << 0.0 << 0.0 << 0.0
350  << 0.0 << Cosine << Sine << 0.0
351  << 0.0 << -Sine << Cosine << 0.0
352  << 0.0 << 0.0 << 0.0 << 1.0;
353  }
354  else
355  {
356  m << 1.0 << 0.0 << 0.0 << 0.0
357  << 0.0 << Cosine << -Sine << 0.0
358  << 0.0 << Sine << Cosine << 0.0
359  << 0.0 << 0.0 << 0.0 << 1.0;
360  }
361 
362  return m;
363 }
364 
365 NEWMAT::Matrix ossimMatrix4x4::createRotationYMatrix(double angle,
366  ossimCoordSysOrientMode orientationMode)
367 {
368  NEWMAT::Matrix m(4,4);
369 
370  double Cosine = cos(angle*RAD_PER_DEG);
371  double Sine = sin(angle*RAD_PER_DEG);
372 
373  if(orientationMode == OSSIM_RIGHT_HANDED)
374  {
375  m << Cosine << 0.0 << -Sine << 0.0
376  << 0.0 << 1.0 << 0.0 << 0.0
377  << Sine << 0.0 << Cosine << 0.0
378  << 0.0 << 0.0 << 0.0 << 1.0;
379  }
380  else
381  {
382  m << Cosine << 0.0 << Sine << 0.0
383  << 0.0 << 1.0 << 0.0 << 0.0
384  << -Sine << 0.0 << Cosine << 0.0
385  << 0.0 << 0.0 << 0.0 << 1.0;
386  }
387 
388  return m;
389 }
390 
391 
392 NEWMAT::Matrix ossimMatrix4x4::createRotationZMatrix(double angle,
393  ossimCoordSysOrientMode orientationMode)
394 {
395  NEWMAT::Matrix m(4,4);
396 
397  double Cosine = cos(angle*RAD_PER_DEG);
398  double Sine = sin(angle*RAD_PER_DEG);
399 
400  if(orientationMode == OSSIM_RIGHT_HANDED)
401  {
402  m << Cosine << Sine << 0.0 << 0.0
403  << -Sine << Cosine << 0.0 << 0.0
404  << 0.0 << 0.0 << 1.0 << 0.0
405  << 0.0 << 0.0 << 0.0 << 1.0;
406  }
407  else
408  {
409  m << Cosine << -Sine << 0.0 << 0.0
410  << Sine << Cosine << 0.0 << 0.0
411  << 0.0 << 0.0 << 1.0 << 0.0
412  << 0.0 << 0.0 << 0.0 << 1.0;
413  }
414 
415  return m;
416 }
417 
418 
419 NEWMAT::Matrix ossimMatrix4x4::createScaleMatrix(double x, double y, double z)
420 {
421  NEWMAT::Matrix m(4, 4);
422 
423  m << x << 0.0 << 0.0 << 0.0
424  << 0.0 << y << 0.0 << 0.0
425  << 0.0 << 0.0 << z << 0.0
426  << 0.0 << 0.0 << 0.0 << 1.0;
427 
428  return m;
429 }
ossimColumnVector3d getEigenValues() const
void EigenValues(const SymmetricMatrix &, DiagonalMatrix &)
Definition: evalue.cpp:286
ossim_uint32 x
ossim::Quaternion getRotate() const
const NEWMAT::Matrix & getData() const
static NEWMAT::Matrix createRotationYMatrix(double angle, ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED)
ossimMatrix4x4 & i()
NEWMAT::Matrix theData
static NEWMAT::Matrix createTranslationMatrix(double x, double y, double z)
ossim_uint32 y
static NEWMAT::Matrix createZero()
A quaternion class.
#define QW
ossimCoordSysOrientMode
void makeRotate(const ossim::Quaternion &quat)
double ossim_float64
value_type length2() const
Length of the quaternion = vec . vec.
void setRotate(const ossim::Quaternion &quat)
static NEWMAT::Matrix createRotationXMatrix(double angle, ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED)
static NEWMAT::Matrix createRotationZMatrix(double angle, ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED)
static NEWMAT::Matrix createScaleMatrix(double X, double Y, double Z)
#define QX
#define QY
static NEWMAT::Matrix createRotateOnly(const ossimMatrix4x4 &aMatrix)
static NEWMAT::Matrix createIdentity()
#define QZ
static NEWMAT::Matrix createRotationMatrix(double angleX, double angleY, double angleZ, ossimCoordSysOrientMode orientationMode=OSSIM_RIGHT_HANDED)
#define RAD_PER_DEG