Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

matrix3.inl

Go to the documentation of this file.
00001 /*
00002     Sheep - A Rigid Body Dynamics Engine
00003     Copyright (C) 2001-2004 Francois Beaune
00004     Contact: http://toxicengine.sourceforge.net/
00005 
00006     This file is part of Sheep.
00007 
00008     Sheep is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     Sheep is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with Sheep; if not, write to the Free Software
00020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 inline
00024 Matrix3::Matrix3() {}
00025 
00026 inline
00027 Matrix3::Matrix3(Real r) {
00028     m_v[0] = m_v[1] = m_v[2] =
00029     m_v[3] = m_v[4] = m_v[5] =
00030     m_v[6] = m_v[7] = m_v[8] = r;
00031 }
00032 
00033 inline
00034 Matrix3::Matrix3(const Matrix3 &m) {
00035     m_v[0] = m.m_v[0];
00036     m_v[1] = m.m_v[1];
00037     m_v[2] = m.m_v[2];
00038     m_v[3] = m.m_v[3];
00039     m_v[4] = m.m_v[4];
00040     m_v[5] = m.m_v[5];
00041     m_v[6] = m.m_v[6];
00042     m_v[7] = m.m_v[7];
00043     m_v[8] = m.m_v[8];
00044 }
00045 
00046 inline
00047 Matrix3 Matrix3::Identity() {
00048     Matrix3 res;
00049 
00050     res.m_v[0] = res.m_v[4] = res.m_v[8] = 1.0;
00051     res.m_v[1] = res.m_v[2] = res.m_v[3] =
00052     res.m_v[5] = res.m_v[6] = res.m_v[7] = 0.0;
00053 
00054     return res;
00055 }
00056 
00057 inline
00058 Matrix3 Matrix3::Rotation(const Quaternion &q) {    // q must be normalized
00059     Matrix3 res;
00060 
00061     res.m_v[0] = 1.0 - 2.0 * (q.m_v.m_y * q.m_v.m_y + q.m_v.m_z * q.m_v.m_z);
00062     res.m_v[1] = 2.0 * (q.m_v.m_x * q.m_v.m_y - q.m_s * q.m_v.m_z);
00063     res.m_v[2] = 2.0 * (q.m_v.m_x * q.m_v.m_z + q.m_s * q.m_v.m_y);
00064     res.m_v[3] = 2.0 * (q.m_v.m_x * q.m_v.m_y + q.m_s * q.m_v.m_z);
00065     res.m_v[4] = 1.0 - 2.0 * (q.m_v.m_x * q.m_v.m_x + q.m_v.m_z * q.m_v.m_z);
00066     res.m_v[5] = 2.0 * (q.m_v.m_y * q.m_v.m_z - q.m_s * q.m_v.m_x);
00067     res.m_v[6] = 2.0 * (q.m_v.m_x * q.m_v.m_z - q.m_s * q.m_v.m_y);
00068     res.m_v[7] = 2.0 * (q.m_v.m_y * q.m_v.m_z + q.m_s * q.m_v.m_x);
00069     res.m_v[8] = 1.0 - 2.0 * (q.m_v.m_x * q.m_v.m_x + q.m_v.m_y * q.m_v.m_y);
00070 
00071     return res;
00072 }
00073 
00074 inline
00075 Matrix3 Matrix3::Rotation(Real angle, const Vector3 &axis) {
00076     //!\todo Implement.
00077     assert(!"Not implemented yet.");
00078     return Matrix3();
00079 }
00080 
00081 inline
00082 Matrix3 Matrix3::Rotation(Real rotx, Real roty, Real rotz) {
00083     const Real a = cos(rotx);
00084     const Real b = sin(rotx);
00085     const Real c = cos(roty);
00086     const Real d = sin(roty);
00087     const Real e = cos(rotz);
00088     const Real f = sin(rotz);
00089 
00090     const Real ad = a * d;
00091     const Real bd = b * d;
00092 
00093     Matrix3 res;
00094 
00095     res.m_v[0] = c * e;
00096     res.m_v[1] = -a * f + bd * e;
00097     res.m_v[2] = b * f + ad * e;
00098     res.m_v[3] = c * f;
00099     res.m_v[4] = a * e + bd * f;
00100     res.m_v[5] = -b * e + ad * f;
00101     res.m_v[6] = -d;
00102     res.m_v[7] = b * c;
00103     res.m_v[8] = a * c;
00104 
00105     return res;
00106 }
00107 
00108 inline
00109 void Matrix3::GetEulerAngles(Real *rotx, Real *roty, Real *rotz) const {
00110     // "Computing Euler angles from a rotation matrix", Gregory G. Slabaugh.
00111     // http://users.ece.gatech.edu/~slabaugh/personal/research/euler/euler.pdf.
00112 
00113     if(m_v[6] != 1.0 && m_v[6] != -1.0) {
00114         const Real theta = -asin(m_v[6]);
00115         const Real inv_cos_theta = 1.0 / cos(theta);
00116 
00117         *rotx = atan2(m_v[7] * inv_cos_theta, m_v[8] * inv_cos_theta);
00118         *roty = theta;
00119         *rotz = atan2(m_v[3] * inv_cos_theta, m_v[0] * inv_cos_theta);
00120     } else {
00121         *rotx = atan2(m_v[1], m_v[2]);
00122 
00123         if(m_v[6] == -1.0)
00124             *roty = PI / 2.0;
00125         else *roty = -PI / 2.0;
00126 
00127         *rotz = 0.0;
00128     }
00129 }
00130 
00131 inline
00132 Matrix3 Matrix3::Scale(const Vector3 &s) {
00133     Matrix3 res;
00134 
00135     res.m_v[0] = s.m_x;
00136     res.m_v[4] = s.m_y;
00137     res.m_v[8] = s.m_z;
00138 
00139     res.m_v[1] = res.m_v[2] = res.m_v[3] =
00140     res.m_v[5] = res.m_v[6] = res.m_v[7] = 0.0;
00141 
00142     return res;
00143 }
00144 
00145 inline
00146 Matrix3 &Matrix3::operator=(Real r) {
00147     m_v[0] = m_v[1] = m_v[2] =
00148     m_v[3] = m_v[4] = m_v[5] =
00149     m_v[6] = m_v[7] = m_v[8] = r;
00150 
00151     return *this;
00152 }
00153 
00154 inline
00155 Matrix3 &Matrix3::operator=(const Matrix3 &m) {
00156     m_v[0] = m.m_v[0];
00157     m_v[1] = m.m_v[1];
00158     m_v[2] = m.m_v[2];
00159     m_v[3] = m.m_v[3];
00160     m_v[4] = m.m_v[4];
00161     m_v[5] = m.m_v[5];
00162     m_v[6] = m.m_v[6];
00163     m_v[7] = m.m_v[7];
00164     m_v[8] = m.m_v[8];
00165 
00166     return *this;
00167 }
00168 
00169 inline
00170 Matrix3 Matrix3::operator+(const Matrix3 &m) const {
00171     Matrix3 res;
00172 
00173     res.m_v[0] = m_v[0] + m.m_v[0];
00174     res.m_v[1] = m_v[1] + m.m_v[1];
00175     res.m_v[2] = m_v[2] + m.m_v[2];
00176     res.m_v[3] = m_v[3] + m.m_v[3];
00177     res.m_v[4] = m_v[4] + m.m_v[4];
00178     res.m_v[5] = m_v[5] + m.m_v[5];
00179     res.m_v[6] = m_v[6] + m.m_v[6];
00180     res.m_v[7] = m_v[7] + m.m_v[7];
00181     res.m_v[8] = m_v[8] + m.m_v[8];
00182 
00183     return res;
00184 }
00185 
00186 inline
00187 Matrix3 Matrix3::operator-(const Matrix3 &m) const {
00188     Matrix3 res;
00189 
00190     res.m_v[0] = m_v[0] - m.m_v[0];
00191     res.m_v[1] = m_v[1] - m.m_v[1];
00192     res.m_v[2] = m_v[2] - m.m_v[2];
00193     res.m_v[3] = m_v[3] - m.m_v[3];
00194     res.m_v[4] = m_v[4] - m.m_v[4];
00195     res.m_v[5] = m_v[5] - m.m_v[5];
00196     res.m_v[6] = m_v[6] - m.m_v[6];
00197     res.m_v[7] = m_v[7] - m.m_v[7];
00198     res.m_v[8] = m_v[8] - m.m_v[8];
00199 
00200     return res;
00201 }
00202 
00203 inline
00204 Matrix3 Matrix3::operator-() const {
00205     Matrix3 res;
00206 
00207     res.m_v[0] = -m_v[0];
00208     res.m_v[1] = -m_v[1];
00209     res.m_v[2] = -m_v[2];
00210     res.m_v[3] = -m_v[3];
00211     res.m_v[4] = -m_v[4];
00212     res.m_v[5] = -m_v[5];
00213     res.m_v[6] = -m_v[6];
00214     res.m_v[7] = -m_v[7];
00215     res.m_v[8] = -m_v[8];
00216 
00217     return res;
00218 }
00219 
00220 inline
00221 Matrix3 Matrix3::operator*(Real r) const {
00222     Matrix3 res;
00223 
00224     res.m_v[0] = m_v[0] * r;
00225     res.m_v[1] = m_v[1] * r;
00226     res.m_v[2] = m_v[2] * r;
00227     res.m_v[3] = m_v[3] * r;
00228     res.m_v[4] = m_v[4] * r;
00229     res.m_v[5] = m_v[5] * r;
00230     res.m_v[6] = m_v[6] * r;
00231     res.m_v[7] = m_v[7] * r;
00232     res.m_v[8] = m_v[8] * r;
00233 
00234     return res;
00235 }
00236 
00237 inline
00238 Matrix3 Matrix3::operator/(Real r) const {
00239     Real inv_r = 1.0 / r;
00240 
00241     Matrix3 res;
00242 
00243     res.m_v[0] = m_v[0] * inv_r;
00244     res.m_v[1] = m_v[1] * inv_r;
00245     res.m_v[2] = m_v[2] * inv_r;
00246     res.m_v[3] = m_v[3] * inv_r;
00247     res.m_v[4] = m_v[4] * inv_r;
00248     res.m_v[5] = m_v[5] * inv_r;
00249     res.m_v[6] = m_v[6] * inv_r;
00250     res.m_v[7] = m_v[7] * inv_r;
00251     res.m_v[8] = m_v[8] * inv_r;
00252 
00253     return res;
00254 }
00255 
00256 inline
00257 Matrix3 &Matrix3::operator+=(const Matrix3 &m) {
00258     m_v[0] += m.m_v[0];
00259     m_v[1] += m.m_v[1];
00260     m_v[2] += m.m_v[2];
00261     m_v[3] += m.m_v[3];
00262     m_v[4] += m.m_v[4];
00263     m_v[5] += m.m_v[5];
00264     m_v[6] += m.m_v[6];
00265     m_v[7] += m.m_v[7];
00266     m_v[8] += m.m_v[8];
00267 
00268     return *this;
00269 }
00270 
00271 inline
00272 Matrix3 &Matrix3::operator-=(const Matrix3 &m) {
00273     m_v[0] -= m.m_v[0];
00274     m_v[1] -= m.m_v[1];
00275     m_v[2] -= m.m_v[2];
00276     m_v[3] -= m.m_v[3];
00277     m_v[4] -= m.m_v[4];
00278     m_v[5] -= m.m_v[5];
00279     m_v[6] -= m.m_v[6];
00280     m_v[7] -= m.m_v[7];
00281     m_v[8] -= m.m_v[8];
00282 
00283     return *this;
00284 }
00285 
00286 inline
00287 Matrix3 &Matrix3::operator*=(Real r) {
00288     m_v[0] *= r;
00289     m_v[1] *= r;
00290     m_v[2] *= r;
00291     m_v[3] *= r;
00292     m_v[4] *= r;
00293     m_v[5] *= r;
00294     m_v[6] *= r;
00295     m_v[7] *= r;
00296     m_v[8] *= r;
00297 
00298     return *this;
00299 }
00300 
00301 inline
00302 Matrix3 &Matrix3::operator/=(Real r) {
00303     Real inv_r = 1.0 / r;
00304 
00305     m_v[0] *= inv_r;
00306     m_v[1] *= inv_r;
00307     m_v[2] *= inv_r;
00308     m_v[3] *= inv_r;
00309     m_v[4] *= inv_r;
00310     m_v[5] *= inv_r;
00311     m_v[6] *= inv_r;
00312     m_v[7] *= inv_r;
00313     m_v[8] *= inv_r;
00314 
00315     return *this;
00316 }
00317 
00318 inline
00319 Matrix3 Matrix3::operator*(const Matrix3 &m) const {
00320     Matrix3 res;
00321 
00322     res.m_v[0] = m_v[0] * m.m_v[0] + m_v[1] * m.m_v[3] + m_v[2] * m.m_v[6];
00323     res.m_v[1] = m_v[0] * m.m_v[1] + m_v[1] * m.m_v[4] + m_v[2] * m.m_v[7];
00324     res.m_v[2] = m_v[0] * m.m_v[2] + m_v[1] * m.m_v[5] + m_v[2] * m.m_v[8];
00325 
00326     res.m_v[3] = m_v[3] * m.m_v[0] + m_v[4] * m.m_v[3] + m_v[5] * m.m_v[6];
00327     res.m_v[4] = m_v[3] * m.m_v[1] + m_v[4] * m.m_v[4] + m_v[5] * m.m_v[7];
00328     res.m_v[5] = m_v[3] * m.m_v[2] + m_v[4] * m.m_v[5] + m_v[5] * m.m_v[8];
00329 
00330     res.m_v[6] = m_v[6] * m.m_v[0] + m_v[7] * m.m_v[3] + m_v[8] * m.m_v[6];
00331     res.m_v[7] = m_v[6] * m.m_v[1] + m_v[7] * m.m_v[4] + m_v[8] * m.m_v[7];
00332     res.m_v[8] = m_v[6] * m.m_v[2] + m_v[7] * m.m_v[5] + m_v[8] * m.m_v[8];
00333 
00334     return res;
00335 }
00336 
00337 inline
00338 Matrix3 &Matrix3::operator*=(const Matrix3 &m) {
00339     Real u, v;
00340 
00341     u = m_v[0] * m.m_v[0] + m_v[1] * m.m_v[3] + m_v[2] * m.m_v[6];
00342     v = m_v[0] * m.m_v[1] + m_v[1] * m.m_v[4] + m_v[2] * m.m_v[7];
00343     m_v[2] = m_v[0] * m.m_v[2] + m_v[1] * m.m_v[5] + m_v[2] * m.m_v[8];
00344     m_v[0] = u;
00345     m_v[1] = v;
00346 
00347     u = m_v[3] * m.m_v[0] + m_v[4] * m.m_v[3] + m_v[5] * m.m_v[6];
00348     v = m_v[3] * m.m_v[1] + m_v[4] * m.m_v[4] + m_v[5] * m.m_v[7];
00349     m_v[5] = m_v[3] * m.m_v[2] + m_v[4] * m.m_v[5] + m_v[5] * m.m_v[8];
00350     m_v[3] = u;
00351     m_v[4] = v;
00352 
00353     u = m_v[6] * m.m_v[0] + m_v[7] * m.m_v[3] + m_v[8] * m.m_v[6];
00354     v = m_v[6] * m.m_v[1] + m_v[7] * m.m_v[4] + m_v[8] * m.m_v[7];
00355     m_v[8] = m_v[6] * m.m_v[2] + m_v[7] * m.m_v[5] + m_v[8] * m.m_v[8];
00356     m_v[6] = u;
00357     m_v[7] = v;
00358 
00359     return *this;
00360 }
00361 
00362 inline
00363 Vector3 Matrix3::operator*(const Vector3 &v) const {
00364     return Vector3(
00365         m_v[0] * v.m_x + m_v[1] * v.m_y + m_v[2] * v.m_z,
00366         m_v[3] * v.m_x + m_v[4] * v.m_y + m_v[5] * v.m_z,
00367         m_v[6] * v.m_x + m_v[7] * v.m_y + m_v[8] * v.m_z);
00368 }
00369 
00370 inline
00371 Real &Matrix3::operator[](int i) {
00372     assert(i >= 0 && i < 9);
00373 
00374     return m_v[i];
00375 }
00376 
00377 inline
00378 const Real &Matrix3::operator[](int i) const {
00379     assert(i >= 0 && i < 9);
00380 
00381     return m_v[i];
00382 }
00383 
00384 inline
00385 Real &Matrix3::operator()(int row, int column) {
00386     assert(row >= 0 && row < 3);
00387     assert(column >= 0 && column < 3);
00388 
00389     return m_v[row + row + row + column];
00390 }
00391 
00392 inline
00393 const Real &Matrix3::operator()(int row, int column) const {
00394     assert(row >= 0 && row < 3);
00395     assert(column >= 0 && column < 3);
00396 
00397     return m_v[row + row + row + column];
00398 }
00399 
00400 inline
00401 Matrix3 Matrix3::Transpose() const {
00402     Matrix3 res;
00403 
00404     res.m_v[0] = m_v[0];
00405     res.m_v[1] = m_v[3];
00406     res.m_v[2] = m_v[6];
00407     res.m_v[3] = m_v[1];
00408     res.m_v[4] = m_v[4];
00409     res.m_v[5] = m_v[7];
00410     res.m_v[6] = m_v[2];
00411     res.m_v[7] = m_v[5];
00412     res.m_v[8] = m_v[8];
00413 
00414     return res;
00415 }
00416 
00417 inline
00418 Matrix3 Matrix3::Inverse() const {
00419     // Compute the matrix inverse using Cramer's rule.
00420 
00421     Real u = m_v[4] * m_v[8] - m_v[5] * m_v[7];
00422     Real v = m_v[5] * m_v[6] - m_v[3] * m_v[8];
00423     Real w = m_v[3] * m_v[7] - m_v[4] * m_v[6];
00424 
00425     Matrix3 res;
00426 
00427     // Compute cofactors.
00428     res.m_v[0] = u;
00429     res.m_v[1] = m_v[2] * m_v[7] - m_v[1] * m_v[8];
00430     res.m_v[2] = m_v[1] * m_v[5] - m_v[2] * m_v[4];
00431     res.m_v[3] = v;
00432     res.m_v[4] = m_v[0] * m_v[8] - m_v[2] * m_v[6];
00433     res.m_v[5] = m_v[2] * m_v[3] - m_v[0] * m_v[5];
00434     res.m_v[6] = w;
00435     res.m_v[7] = m_v[1] * m_v[6] - m_v[0] * m_v[7];
00436     res.m_v[8] = m_v[0] * m_v[4] - m_v[1] * m_v[3];
00437 
00438     // Compute matrix determinant.
00439     Real det = m_v[0] * u + m_v[1] * v + m_v[2] * w;
00440 
00441     ///!\todo Throw an exception if the matrix to be inverted
00442     //! is singular (i.e. if fabs(det) <= EPSILON).
00443     assert(det != 0.0);
00444 
00445     // Multiply the obtained matrix by the reciprocal of the
00446     // input matrix determinant.
00447     Real inv_det = 1.0 / det;
00448     res.m_v[0] *= inv_det;
00449     res.m_v[1] *= inv_det;
00450     res.m_v[2] *= inv_det;
00451     res.m_v[3] *= inv_det;
00452     res.m_v[4] *= inv_det;
00453     res.m_v[5] *= inv_det;
00454     res.m_v[6] *= inv_det;
00455     res.m_v[7] *= inv_det;
00456     res.m_v[8] *= inv_det;
00457 
00458     return res;
00459 }
00460 
00461 inline
00462 Real Matrix3::Determinant() const {
00463     return
00464         m_v[0] * (m_v[4] * m_v[8] - m_v[5] * m_v[7]) +
00465         m_v[1] * (m_v[5] * m_v[6] - m_v[3] * m_v[8]) +
00466         m_v[2] * (m_v[3] * m_v[7] - m_v[4] * m_v[6]);
00467 }
00468 
00469 inline
00470 Real Matrix3::Trace() const {
00471     return m_v[0] + m_v[4] + m_v[8];
00472 }
00473 
00474 inline
00475 Matrix3 operator*(Real r, const Matrix3 &m) {
00476     return m * r;
00477 }

Generated on Tue May 11 01:31:50 2004 for toxic by doxygen 1.3.6