/* * Copyright (C) 2008 * Robert Bosch LLC * Research and Technology Center North America * Palo Alto, California * * All rights reserved. * *------------------------------------------------------------------------------ * project ....: Autonomous Technologies * file .......: rtcSMat3.h * authors ....: Benjamin Pitzer * organization: Robert Bosch LLC * creation ...: 08/16/2006 * modified ...: $Date: 2009-01-21 18:19:16 -0800 (Wed, 21 Jan 2009) $ * changed by .: $Author: benjaminpitzer $ * revision ...: $Revision: 14 $ */ #ifndef RTC_SMAT3_H #define RTC_SMAT3_H //== INCLUDES ================================================================== #include "rtcMath.h" #include "rtcVec3.h" #include "rtcSMat.h" //== NAMESPACES ================================================================ namespace rtc { // Forward declarations template class SMat; // MxM Square Matrix template class Vec3; // 3d Vector template class SMat3; // 3x3 Matrix /** * A 3x3 matrix. * A specialization of a square matrix. */ template class SMat3: public SMat { public: // Data using SMat::x; using SMat::set; // Constructors SMat3(); SMat3(const T* d); SMat3(const T diagVal); SMat3(const Vec3& diagVec); SMat3(const Mat& m); SMat3(const T x11, const T x12, const T x13, const T x21, const T x22, const T x23, const T x31, const T x32, const T x33); SMat3(const Vec3& q0, const Vec3& q1, const Vec3& q2); // Casting Operation template SMat3(const Mat& m); // Named Constructors static SMat3 fromRows(const Vec3& v0, const Vec3& v1, const Vec3& v2); static SMat3 fromCols(const Vec3& v0, const Vec3& v1, const Vec3& v2); // Mutators void set(const T x11, const T x12, const T x13, const T x21, const T x22, const T x23, const T x31, const T x32, const T x33); void setRows(const Vec3& v0, const Vec3& v1, const Vec3& v2); void setCols(const Vec3& v0, const Vec3& v1, const Vec3& v2); // Determinant, inverse, etc. T det() const; SMat3 inverted() const; int invert(); }; // Declare a few common typdefs typedef SMat3 SMat3b; typedef SMat3 SMat3c; typedef SMat3 SMat3uc; typedef SMat3 SMat3i; typedef SMat3 SMat3f; typedef SMat3 SMat3d; //============================================================================== // SMat3 //============================================================================== // Constructors /** Ctor that doesn't initialize anything. */ template inline SMat3::SMat3() {} /** Ctor that initializes from an array. * @param d the (row major) data array of length 4 */ template inline SMat3::SMat3(const T* d) : SMat(d) {} /** Ctor that makes a multiple of the identity matrix. * @param diagVal the value to which all diagonal entries will be set */ template inline SMat3::SMat3(const T diagVal) : SMat(diagVal) {} /** Ctor that makes a (mostly) zero matrix with diagonal entries from vec. * @param diagVec the vector of values that should appear on the diagonal */ template inline SMat3::SMat3(const Vec3& diagVec) : SMat(diagVec) { } /** Ctor that initializes from a Mat. */ template inline SMat3::SMat3(const Mat& m) : SMat(m) {} /** Ctor that initializes matrix entries directly. */ template inline SMat3::SMat3(const T x11, const T x12, const T x13, const T x21, const T x22, const T x23, const T x31, const T x32, const T x33) { set(x11, x12, x13, x21, x22, x23, x31, x32, x33); } /** Ctor that initializes matrix from columns. */ template inline SMat3::SMat3(const Vec3& v0, const Vec3& v1, const Vec3& v2) { setCols(v0,v1,v2); } // Casting Operation /** Casting Ctor that initializes from a Mat with type cast */ template template inline SMat3::SMat3(const Mat& m) : SMat(m) {} // Named Constructors /** Create matrix from rows. */ template inline SMat3 SMat3::fromRows(const Vec3& v0, const Vec3& v1, const Vec3& v2) { SMat3 m; m.setRows(v0,v1,v2); return m; } /** Create matrix from columns. */ template inline SMat3 SMat3::fromCols(const Vec3& v0, const Vec3& v1, const Vec3& v2) { SMat3 m; m.setCols(v0,v1,v2); return m; } // Mutators /** Set matrix given entries directly. */ template inline void SMat3::set(const T x11, const T x12, const T x13, const T x21, const T x22, const T x23, const T x31, const T x32, const T x33) { x[0] = x11; x[1] = x12; x[2] = x13; x[3] = x21; x[4] = x22; x[5] = x23; x[6] = x31; x[7] = x32; x[8] = x33; } /** Set the rows of the matrix. */ template inline void SMat3::setRows(const Vec3& v0, const Vec3& v1, const Vec3& v2) { setRow(0,v0); setRow(1,v1); setRow(2,v2); } /** Set the columns of the matrix. */ template inline void SMat3::setCols(const Vec3& v0, const Vec3& v1, const Vec3& v2) { setCol(0,v0); setCol(1,v1); setCol(2,v2); } // Determinant and Inverse /** Calculate determinant. */ template inline T SMat3::det() const { return (x[0]*(x[4]*x[8] - x[7]*x[5]) - x[1]*(x[3]*x[8] - x[6]*x[5]) + x[2]*(x[3]*x[7] - x[6]*x[4])); } /** Invert the matrix. (matrix set to its inverse) * @todo consider throwing exception instead */ template inline SMat3 SMat3::inverted() const { T d = det(); if (d == 0.0) { throw Exception( "SMat3::inverted(): error, can't take inverse of singular matrix."); } T di = T(1)/d; return SMat3((x[4]*x[8] - x[5]*x[7])*di, (x[2]*x[7] - x[1]*x[8])*di, (x[1]*x[5] - x[2]*x[4])*di, (x[5]*x[6] - x[3]*x[8])*di, (x[0]*x[8] - x[2]*x[6])*di, (x[2]*x[3] - x[0]*x[5])*di, (x[3]*x[7] - x[4]*x[6])*di, (x[1]*x[6] - x[0]*x[7])*di, (x[0]*x[4] - x[1]*x[3])*di); } /** Perform inverse in place */ template inline int SMat3::invert() { T d = det(); if (d == 0.0) { throw Exception( "SMat3::inverted(): error, can't take inverse of singular matrix."); } T di = T(1)/d; set((x[4]*x[8] - x[5]*x[7])*di, (x[2]*x[7] - x[1]*x[8])*di, (x[1]*x[5] - x[2]*x[4])*di, (x[5]*x[6] - x[3]*x[8])*di, (x[0]*x[8] - x[2]*x[6])*di, (x[2]*x[3] - x[0]*x[5])*di, (x[3]*x[7] - x[4]*x[6])*di, (x[1]*x[6] - x[0]*x[7])*di, (x[0]*x[4] - x[1]*x[3])*di); return 0; } //============================================================================== } // namespace rtc //============================================================================== #endif // RTC_SMAT3_H defined //==============================================================================