ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE-4/src/math/SquareMatrix3.hpp
(Generate patch)

Comparing trunk/OOPSE-4/src/math/SquareMatrix3.hpp (file contents):
Revision 1592 by tim, Mon Oct 18 17:07:27 2004 UTC vs.
Revision 1594 by tim, Mon Oct 18 23:13:23 2004 UTC

# Line 72 | Line 72 | namespace oopse {
72                  if (this == &m)
73                      return *this;
74                   SquareMatrix<Real, 3>::operator=(m);
75 +                 return *this;
76              }
77  
78              /**
# Line 126 | Line 127 | namespace oopse {
127               * @param w the first element
128               * @param x the second element
129               * @param y the third element
130 <             * @parma z the fourth element
130 >             * @param z the fourth element
131              */
132              void setupRotMat(Real w, Real x, Real y, Real z) {
133                  Quaternion<Real> q(w, x, y, z);
# Line 237 | Line 238 | namespace oopse {
238                  return myEuler;
239              }
240              
241 +            /** Returns the determinant of this matrix. */
242 +            Real determinant() const {
243 +                Real x,y,z;
244 +
245 +                x = data_[0][0] * (data_[1][1] * data_[2][2] - data_[1][2] * data_[2][1]);
246 +                y = data_[0][1] * (data_[1][2] * data_[2][0] - data_[1][0] * data_[2][2]);
247 +                z = data_[0][2] * (data_[1][0] * data_[2][1] - data_[1][1] * data_[2][0]);
248 +
249 +                return(x + y + z);
250 +            }            
251 +            
252              /**
253               * Sets the value of this matrix to  the inversion of itself.
254               * @note since simple algorithm can be applied to inverse the 3 by 3 matrix, we hide the
255               * implementation of inverse in SquareMatrix class
256               */
257 <            void  inverse() {
257 >            SquareMatrix3<Real>  inverse() {
258 >                SquareMatrix3<Real> m;
259 >                double det = determinant();
260 >                if (fabs(det) <= oopse::epsilon) {
261 >                //"The method was called on a matrix with |determinant| <= 1e-6.",
262 >                //"This is a runtime or a programming error in your application.");
263 >                }
264  
265 +                m(0, 0) = data_[1][1]*data_[2][2] - data_[1][2]*data_[2][1];
266 +                m(1, 0) = data_[1][2]*data_[2][0] - data_[1][0]*data_[2][2];
267 +                m(2, 0) = data_[1][0]*data_[2][1] - data_[1][1]*data_[2][0];
268 +                m(0, 1) = data_[2][1]*data_[0][2] - data_[2][2]*data_[0][1];
269 +                m(1, 1) = data_[2][2]*data_[0][0] - data_[2][0]*data_[0][2];
270 +                m(2, 1) = data_[2][0]*data_[0][1] - data_[2][1]*data_[0][0];
271 +                m(0, 2) = data_[0][1]*data_[1][2] - data_[0][2]*data_[1][1];
272 +                m(1, 2) = data_[0][2]*data_[1][0] - data_[0][0]*data_[1][2];
273 +                m(2, 2) = data_[0][0]*data_[1][1] - data_[0][1]*data_[1][0];
274 +
275 +                m /= det;
276 +                return m;
277              }
278  
279 <            void diagonalize() {
279 >            void diagonalize(SquareMatrix3<Real>& a, Vector3<Real>& w, SquareMatrix3<Real>& v) {
280 >                int i,j,k,maxI;
281 >                Real tmp, maxVal;
282 >                Vector3<Real> v_maxI, v_k, v_j;
283  
284 +                // diagonalize using Jacobi
285 +                jacobi(a, w, v);
286 +
287 +                // if all the eigenvalues are the same, return identity matrix
288 +                if (w[0] == w[1] && w[0] == w[2] ){
289 +                      v = SquareMatrix3<Real>::identity();
290 +                      return
291 +                }
292 +
293 +                // transpose temporarily, it makes it easier to sort the eigenvectors
294 +                v = v.tanspose();
295 +                
296 +                // if two eigenvalues are the same, re-orthogonalize to optimally line
297 +                // up the eigenvectors with the x, y, and z axes
298 +                for (i = 0; i < 3; i++) {
299 +                    if (w((i+1)%3) == w((i+2)%3)) {// two eigenvalues are the same
300 +                    // find maximum element of the independant eigenvector
301 +                    maxVal = fabs(v(i, 0));
302 +                    maxI = 0;
303 +                    for (j = 1; j < 3; j++) {
304 +                        if (maxVal < (tmp = fabs(v(i, j)))){
305 +                            maxVal = tmp;
306 +                            maxI = j;
307 +                        }
308 +                    }
309 +                    
310 +                    // swap the eigenvector into its proper position
311 +                    if (maxI != i) {
312 +                        tmp = w(maxI);
313 +                        w(maxI) = w(i);
314 +                        w(i) = tmp;
315 +
316 +                        v.swapRow(i, maxI);
317 +                    }
318 +                    // maximum element of eigenvector should be positive
319 +                    if (v(maxI, maxI) < 0) {
320 +                        v(maxI, 0) = -v(maxI, 0);
321 +                        v(maxI, 1) = -v(maxI, 1);
322 +                        v(maxI, 2) = -v(maxI, 2);
323 +                    }
324 +
325 +                    // re-orthogonalize the other two eigenvectors
326 +                    j = (maxI+1)%3;
327 +                    k = (maxI+2)%3;
328 +
329 +                    v(j, 0) = 0.0;
330 +                    v(j, 1) = 0.0;
331 +                    v(j, 2) = 0.0;
332 +                    v(j, j) = 1.0;
333 +
334 +                    /** @todo */
335 +                    v_maxI = v.getRow(maxI);
336 +                    v_j = v.getRow(j);
337 +                    v_k = cross(v_maxI, v_j);
338 +                    v_k.normailze();
339 +                    v_j = cross(v_k, v_maxI);
340 +                    v.setRow(j, v_j);
341 +                    v.setRow(k, v_k);
342 +
343 +
344 +                    // transpose vectors back to columns
345 +                    v = v.transpose();
346 +                    return;
347 +                    }
348 +                }
349 +
350 +                // the three eigenvalues are different, just sort the eigenvectors
351 +                // to align them with the x, y, and z axes
352 +
353 +                // find the vector with the largest x element, make that vector
354 +                // the first vector
355 +                maxVal = fabs(v(0, 0));
356 +                maxI = 0;
357 +                for (i = 1; i < 3; i++) {
358 +                    if (maxVal < (tmp = fabs(v(i, 0)))) {
359 +                        maxVal = tmp;
360 +                        maxI = i;
361 +                    }
362 +                }
363 +
364 +                // swap eigenvalue and eigenvector
365 +                if (maxI != 0) {
366 +                    tmp = w(maxI);
367 +                    w(maxI) = w(0);
368 +                    w(0) = tmp;
369 +                    v.swapRow(maxI, 0);
370 +                }
371 +                // do the same for the y element
372 +                if (fabs(v(1, 1)) < fabs(v(2, 1))) {
373 +                    tmp = w(2);
374 +                    w(2) = w(1);
375 +                    w(1) = tmp;
376 +                    v.swapRow(2, 1);
377 +                }
378 +
379 +                // ensure that the sign of the eigenvectors is correct
380 +                for (i = 0; i < 2; i++) {
381 +                    if (v(i, i) < 0) {
382 +                        v(i, 0) = -v(i, 0);
383 +                        v(i, 1) = -v(i, 1);
384 +                        v(i, 2) = -v(i, 2);
385 +                    }
386 +                }
387 +
388 +                // set sign of final eigenvector to ensure that determinant is positive
389 +                if (determinant(v) < 0) {
390 +                    v(2, 0) = -v(2, 0);
391 +                    v(2, 1) = -v(2, 1);
392 +                    v(2, 2) = -v(2, 2);
393 +                }
394 +
395 +                // transpose the eigenvectors back again
396 +                v = v.transpose();
397 +                return ;
398              }
399      };
400  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines