Quaternion.cpp

Go to the documentation of this file.
00001 /*************************************************************************
00002 *                                                                       *
00003 * Open Physics Abstraction Layer                                        *
00004 * Copyright (C) 2004-2005                                               *
00005 * Alan Fischer  alan.fischer@gmail.com                                  *
00006 * Andres Reinot  andres@reinot.com                                      *
00007 * Tyler Streeter  tylerstreeter@gmail.com                               *
00008 * Oleksandr Lozitskiy mr.olexander@gmail.com                            *
00009 * All rights reserved.                                                  *
00010 * Web: opal.sourceforge.net                                             *
00011 *                                                                       *
00012 * This library is free software; you can redistribute it and/or         *
00013 * modify it under the terms of EITHER:                                  *
00014 *   (1) The GNU Lesser General Public License as published by the Free  *
00015 *       Software Foundation; either version 2.1 of the License, or (at  *
00016 *       your option) any later version. The text of the GNU Lesser      *
00017 *       General Public License is included with this library in the     *
00018 *       file license-LGPL.txt.                                          *
00019 *   (2) The BSD-style license that is included with this library in     *
00020 *       the file license-BSD.txt.                                       *
00021 *                                                                       *
00022 * This library is distributed in the hope that it will be useful,       *
00023 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
00025 * license-LGPL.txt and license-BSD.txt for more details.                *
00026 *                                                                       *
00027 *************************************************************************/
00028 
00029 // class headers
00030 #include "Quaternion.h"
00031 
00032 // system headers
00033 #include <cassert>
00034 
00035 // project headers
00036 #include "Vec3r.h"
00037 
00038 namespace opal
00039 {
00040     Quaternion::Quaternion()
00041     {
00042         w = 0;
00043         x = 0;
00044         y = 0;
00045         z = 0;
00046     }
00047 
00048     Quaternion::Quaternion( real ww, real xx, real yy, real zz )
00049     {
00050         w = ww;
00051         x = xx;
00052         y = yy;
00053         z = zz;
00054     }
00055 
00056     Quaternion::Quaternion( const Quaternion& src )
00057     {
00058         w = src.w;
00059         x = src.x;
00060         y = src.y;
00061         z = src.z;
00062     }
00063 
00064     void Quaternion::set( real ww, real xx, real yy, real zz    )
00065     {
00066         w = ww;
00067         x = xx;
00068         y = yy;
00069         z = zz;
00070     }
00071 
00072     real Quaternion::lengthSquared() const
00073     {
00074         return w * w + x * x + y * y + z * z;
00075     }
00076 
00077     real Quaternion::length() const
00078     {
00079         return sqrt( lengthSquared() );
00080     }
00081 
00082     void Quaternion::normalize()
00083     {
00084         real len = length();
00085         if ( len > 0 )
00086         {
00087             real factor = 1 / len;
00088             ( *this ) = ( *this ) * factor;
00089         }
00090     }
00091 
00092     void Quaternion::getAngleAxis( real& angle, Vec3r& axis ) const
00093     {
00094         real sqrLen = x * x + y * y + z * z;
00095 
00096         if ( sqrLen > 0 )
00097         {
00098             angle = 2 * acos( w );
00099             real invLen = 1 / sqrt( sqrLen );
00100             axis.x = x * invLen;
00101             axis.y = y * invLen;
00102             axis.z = z * invLen;
00103         }
00104         else
00105         {
00106             angle = 0;
00107             axis.x = 1;
00108             axis.y = 0;
00109             axis.z = 0;
00110         }
00111 
00112         // convert to degrees
00113         angle = radToDeg( angle );
00114     }
00115 
00116     real Quaternion::getRoll() const
00117     {
00118         return radToDeg( atan2( 2 * ( y * z + w * x ),
00119                                 w * w - x * x - y * y +
00120                                 z * z ) );
00121     }
00122 
00123     real Quaternion::getPitch() const
00124     {
00125         return radToDeg( asin( -2 * ( x * z - w * y ) ) );
00126     }
00127 
00128     real Quaternion::getYaw() const
00129     {
00130         return radToDeg( atan2( 2 * ( x * y + w * z ),
00131                                 w * w + x * x - y * y -
00132                                 z * z ) );
00133     }
00134 
00135     real & Quaternion::operator[] ( unsigned int i )
00136     {
00137         switch ( i )
00138         {
00139             case 0: return w;
00140             case 1: return x;
00141             case 2: return y;
00142             case 3: return z;
00143         }
00144         assert( i < 4 );
00145         return w;
00146     }
00147 
00148     const real & Quaternion::operator[] ( unsigned int i ) const
00149     {
00150         switch ( i )
00151         {
00152             case 0: return w;
00153             case 1: return x;
00154             case 2: return y;
00155             case 3: return z;
00156         }
00157         assert( i < 4 );
00158         return w;
00159     }
00160 
00161     Quaternion operator+( const Quaternion &q1, const Quaternion &q2 )
00162     {
00163         return Quaternion( q1.w + q2.w, q1.x + q2.x, q1.y + q2.y, q1.z + q2.z );
00164     }
00165 
00166     Quaternion operator-( const Quaternion &q1, const Quaternion &q2 )
00167     {
00168         return Quaternion( q1.w - q2.w, q1.x - q2.x, q1.y - q2.y, q1.z - q2.z );
00169     }
00170 
00171     bool operator==( const Quaternion &q1, const Quaternion &q2 )
00172     {
00173         if ( !areEqual( q1.w, q2.w ) || !areEqual( q1.x , q2.x ) ||
00174                 !areEqual( q1.y , q2.y ) || !areEqual( q1.z , q2.z ) )
00175             return false;
00176         else
00177             return true;
00178     }
00179 
00180     bool operator!=( const Quaternion &q1, const Quaternion &q2 )
00181     {
00182         if ( !areEqual( q1.w, q2.w ) || !areEqual( q1.x , q2.x ) ||
00183                 !areEqual( q1.y , q2.y ) || !areEqual( q1.z , q2.z ) )
00184             return true;
00185         else
00186             return false;
00187     }
00188 
00189     Quaternion operator*( const Quaternion& q, real scalar )
00190     {
00191         return Quaternion( scalar * q.w, scalar * q.x, scalar * q.y, scalar * q.z );
00192     }
00193 
00194     Quaternion operator*( real scalar, const Quaternion& q )
00195     {
00196         return Quaternion( scalar * q.w, scalar * q.x, scalar * q.y, scalar * q.z );
00197     }
00198 
00199     std::ostream& operator<<( std::ostream& o, const Quaternion& q )
00200     {
00201         return o << "[" << q.w << " " << q.x << " " << q.y << " " << q.z << "]";
00202     }
00203 }

Generated on Tue May 16 17:49:52 2006 for OPAL by  doxygen 1.4.6-NO