Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members

quat.hxx

00001 
00002 // 
00003 // Copyright (C) 2006 James M. Lawrence.  All rights reserved.
00004 // 
00005 // software: esve-1.0.3
00006 // file: esve/math/quat.hxx
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions
00010 // are met:
00011 // 
00012 // 1. Redistributions of source code must retain the above copyright
00013 //    notice, this list of conditions and the following disclaimer.
00014 // 
00015 // 2. The origin of this software must not be misrepresented; you must
00016 //    not claim that you wrote the original software.  If you use this
00017 //    software in a product, an acknowledgment in the product 
00018 //    documentation would be appreciated but is not required.
00019 // 
00020 // 3. Altered source versions must be plainly marked as such, and must
00021 //    not be misrepresented as being the original software.
00022 // 
00023 // 4. The name of the author may not be used to endorse or promote
00024 //    products derived from this software without specific prior written
00025 //    permission.
00026 // 
00027 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY,
00028 // AND WITH NO CLAIM AS TO ITS SUITABILITY FOR ANY PURPOSE.  IN NO EVENT
00029 // SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM WHATSOEVER MADE IN CONNECTION
00030 // TO THIS SOFTWARE.
00031 // 
00033 //
00034 // quaternions.
00035 //
00036 // A quaternion whose real part is zero is called a 'pure quaternion',
00037 // or a 'pure', and is represented here by the 'pure' class.
00038 //
00039 // This leads to a naming conflict in the analogy with complex
00040 // numbers.  The <complex> header declares
00041 //
00042 //     template<typename F> F real( const complex<F> & ) ;
00043 //     template<typename F> F imag( const complex<F> & ) ;
00044 //
00045 // A function named 'pure' would conflict with the constructor for the
00046 // pure class, and it would be wrong to construct a pure from a
00047 // quaternion due to the resulting loss of data.  Therefore we need
00048 // new names,
00049 //
00050 //     template<typename F> F       realpart( const quat<F> & ) ;
00051 //     template<typename F> pure<F> purepart( const quat<F> & ) ;
00052 //
00053 // instead of just 'real' and 'pure' as one might initially expect.
00054 //
00055 // quat(w, x, y, z) constructs a quaternion with w as the real part.
00056 // Note, however, that the real part appears last in the data layout
00057 // (for OpenGL vertex arrays).
00058 //
00059 // I have disallowed as many conversions as possible, because
00060 // conversions are stupid.
00061 //
00062 // For machines whose float multiply is relatively more expensive,
00063 // defining QUAT_CONSERVE_MULTIPLIES may give better performance.
00064 //
00065 
00066 #ifndef esve_math_quat_hxx
00067 #define esve_math_quat_hxx
00068 
00069 #include <istream>
00070 #include <ostream>
00071 #include <cmath>
00072 
00073 namespace esve { namespace math {
00074 
00075 namespace quat_namespace {
00076 
00077 template<typename F> class quat ;
00078 template<typename F> class pure ;
00079 
00080 template<typename F> F realpart( const quat<F> & ) ;
00081 template<typename F> F realpart( const pure<F> & ) ;
00082 
00083 template<typename F> const pure<F>   purepart( const quat<F> & ) ;
00084 template<typename F> const pure<F> & purepart( const pure<F> & ) ;
00085 
00086 template<typename F> F norm( const quat<F> & ) ;
00087 template<typename F> F norm( const pure<F> & ) ;
00088 
00089 template<typename F> F abs( const quat<F> & ) ;
00090 template<typename F> F abs( const pure<F> & ) ;
00091 
00092 template<typename F> quat<F> conj( const quat<F> & ) ;
00093 template<typename F> pure<F> conj( const pure<F> & ) ;
00094 
00095 template<typename F> quat<F> inv( const quat<F> & ) ;
00096 template<typename F> pure<F> inv( const pure<F> & ) ;
00097 
00098 template<typename F> F dot( const quat<F> &, const quat<F> & ) ;
00099 template<typename F> F dot( const quat<F> &, const pure<F> & ) ;
00100 template<typename F> F dot( const pure<F> &, const quat<F> & ) ;
00101 template<typename F> F dot( const pure<F> &, const pure<F> & ) ;
00102 
00103 template<typename F> F dot( const quat<F> &, F ) ;
00104 template<typename F> F dot( const pure<F> &, F ) ;
00105 template<typename F> F dot( F, const quat<F> & ) ;
00106 template<typename F> F dot( F, const pure<F> & ) ;
00107 
00108 template<typename F> pure<F> cross( const quat<F> &, const quat<F> & ) ;
00109 template<typename F> pure<F> cross( const quat<F> &, const pure<F> & ) ;
00110 template<typename F> pure<F> cross( const pure<F> &, const quat<F> & ) ;
00111 template<typename F> pure<F> cross( const pure<F> &, const pure<F> & ) ;
00112 
00113 template<typename F> pure<F> cross( const quat<F> &, F ) ;
00114 template<typename F> pure<F> cross( const pure<F> &, F ) ;
00115 template<typename F> pure<F> cross( F, const quat<F> & ) ;
00116 template<typename F> pure<F> cross( F, const pure<F> & ) ;
00117 
00118 template<typename F> quat<F> exp( const quat<F> & ) ;
00119 template<typename F> quat<F> exp( const pure<F> & ) ;
00120 
00121 template<typename F> quat<F> log( const quat<F> & ) ;
00122 template<typename F> quat<F> log( const pure<F> & ) ;
00123 
00124 template<typename F> quat<F> cos( const quat<F> & ) ;
00125 template<typename F> quat<F> cos( const pure<F> & ) ;
00126 template<typename F> quat<F> sin( const quat<F> & ) ;
00127 template<typename F> quat<F> sin( const pure<F> & ) ;
00128 template<typename F> quat<F> tan( const quat<F> & ) ;
00129 template<typename F> quat<F> tan( const pure<F> & ) ;
00130 template<typename F> quat<F> cosh( const quat<F> & ) ;
00131 template<typename F> quat<F> cosh( const pure<F> & ) ;
00132 template<typename F> quat<F> sinh( const quat<F> & ) ;
00133 template<typename F> quat<F> sinh( const pure<F> & ) ;
00134 template<typename F> quat<F> tanh( const quat<F> & ) ;
00135 template<typename F> quat<F> tanh( const pure<F> & ) ;
00136 
00137 template<typename F> quat<F> pow( const quat<F> &, unsigned int ) ;
00138 template<typename F> quat<F> pow( const quat<F> &, int ) ;
00139 template<typename F> quat<F> pow( const quat<F> &, F ) ;
00140 template<typename F> quat<F> pow( F, const quat<F> & ) ;
00141 template<typename F> quat<F> pow( const pure<F> &, unsigned int ) ;
00142 template<typename F> quat<F> pow( const pure<F> &, int ) ;
00143 template<typename F> quat<F> pow( const pure<F> &, F ) ;
00144 template<typename F> quat<F> pow( F, const pure<F> & ) ;
00145 
00146 template<typename F> quat<F> sqrt( const quat<F> & ) ;
00147 template<typename F> quat<F> sqrt( const pure<F> & ) ;
00148 
00149 template<typename F> quat<F> operator+( const quat<F> &, const quat<F> & ) ;
00150 template<typename F> quat<F> operator+( const quat<F> &, const pure<F> & ) ;
00151 template<typename F> quat<F> operator+( const pure<F> &, const quat<F> & ) ;
00152 template<typename F> pure<F> operator+( const pure<F> &, const pure<F> & ) ;
00153 
00154 template<typename F> quat<F> operator+( const quat<F> &, F ) ;
00155 template<typename F> quat<F> operator+( const pure<F> &, F ) ;
00156 template<typename F> quat<F> operator+( F, const quat<F> & ) ;
00157 template<typename F> quat<F> operator+( F, const pure<F> & ) ;
00158 
00159 template<typename F> const quat<F> & operator+( const quat<F> & ) ;
00160 template<typename F> const pure<F> & operator+( const pure<F> & ) ;
00161 
00162 template<typename F> quat<F> operator-( const quat<F> &, const quat<F> & ) ;
00163 template<typename F> quat<F> operator-( const quat<F> &, const pure<F> & ) ;
00164 template<typename F> quat<F> operator-( const pure<F> &, const quat<F> & ) ;
00165 template<typename F> pure<F> operator-( const pure<F> &, const pure<F> & ) ;
00166 
00167 template<typename F> quat<F> operator-( const quat<F> &, F ) ;
00168 template<typename F> quat<F> operator-( const pure<F> &, F ) ;
00169 template<typename F> quat<F> operator-( F, const quat<F> & ) ;
00170 template<typename F> quat<F> operator-( F, const pure<F> & ) ;
00171 
00172 template<typename F> quat<F> operator-( const quat<F> & ) ;
00173 template<typename F> pure<F> operator-( const pure<F> & ) ;
00174 
00175 template<typename F> quat<F> operator*( const quat<F> &, const quat<F> & ) ;
00176 template<typename F> quat<F> operator*( const quat<F> &, const pure<F> & ) ;
00177 template<typename F> quat<F> operator*( const pure<F> &, const quat<F> & ) ;
00178 template<typename F> quat<F> operator*( const pure<F> &, const pure<F> & ) ;
00179 
00180 template<typename F> quat<F> operator*( const quat<F> &, F ) ;
00181 template<typename F> pure<F> operator*( const pure<F> &, F ) ;
00182 template<typename F> quat<F> operator*( F, const quat<F> & ) ;
00183 template<typename F> pure<F> operator*( F, const pure<F> & ) ;
00184 
00185 template<typename F> quat<F> operator/( const quat<F> &, F ) ;
00186 template<typename F> pure<F> operator/( const pure<F> &, F ) ;
00187 
00188 template<typename F> bool operator==( const quat<F> &, const quat<F> & ) ;
00189 template<typename F> bool operator==( const quat<F> &, const pure<F> & ) ;
00190 template<typename F> bool operator==( const pure<F> &, const quat<F> & ) ;
00191 template<typename F> bool operator==( const pure<F> &, const pure<F> & ) ;
00192 
00193 template<typename F> bool operator==( const quat<F> &, F ) ;
00194 template<typename F> bool operator==( const pure<F> &, F ) ;
00195 template<typename F> bool operator==( F, const quat<F> & ) ;
00196 template<typename F> bool operator==( F, const pure<F> & ) ;
00197 
00198 template<typename F> bool operator!=( const quat<F> &, const quat<F> & ) ;
00199 template<typename F> bool operator!=( const quat<F> &, const pure<F> & ) ;
00200 template<typename F> bool operator!=( const pure<F> &, const quat<F> & ) ;
00201 template<typename F> bool operator!=( const pure<F> &, const pure<F> & ) ;
00202 
00203 template<typename F> bool operator!=( const quat<F> &, F ) ;
00204 template<typename F> bool operator!=( const pure<F> &, F ) ;
00205 template<typename F> bool operator!=( F, const quat<F> & ) ;
00206 template<typename F> bool operator!=( F, const pure<F> & ) ;
00207 
00208 template< typename F, typename T_Char, typename T_Traits >
00209 std::basic_ostream<T_Char, T_Traits> &
00210 operator<<( std::basic_ostream<T_Char, T_Traits> & , const quat<F> & ) ;
00211 
00212 template< typename F, typename T_Char, typename T_Traits >
00213 std::basic_ostream<T_Char, T_Traits> &
00214 operator<<( std::basic_ostream<T_Char, T_Traits> & , const pure<F> & ) ;
00215 
00216 template< typename F, typename T_Char, typename T_Traits >
00217 std::basic_istream<T_Char, T_Traits> &
00218 operator>>( std::basic_istream<T_Char, T_Traits> & , quat<F> & ) ;
00219 
00220 template< typename F, typename T_Char, typename T_Traits >
00221 std::basic_istream<T_Char, T_Traits> &
00222 operator>>( std::basic_istream<T_Char, T_Traits> & , pure<F> & ) ;
00223 
00224 namespace scalar_func {
00225 template< typename F > F realpart( F a )  ;
00226 template< typename F > F purepart( F a )  ;
00227 template< typename F > F norm( F a )  ;
00228 template< typename F > F conj( F a )  ;
00229 template< typename F > F inv( F a )  ;
00230 template< typename F > F dot( F a, F b )  ;
00231 template< typename F > F cross( F a, F b )  ;
00232 using std::abs ;
00233 using std::exp ;
00234 using std::log ;
00235 using std::cos ;
00236 using std::sin ;
00237 using std::cosh ;
00238 using std::sinh ;
00239 using std::pow ;
00240 using std::sqrt ;
00241 using std::atan2 ;
00242 } // namespace scalar_func
00243 
00244 template< typename F >
00245 class quat
00246 {
00247 public:
00248     typedef F value_type ;
00249 
00250     quat() ;
00251     quat( F w, F x, F y, F z ) ;
00252     quat( F w, const pure<F> & ) ;
00253     explicit quat( const pure<F> & ) ;
00254     explicit quat( F ) ;
00255 
00256     F w() const ;
00257     F x() const ;
00258     F y() const ;
00259     F z() const ;
00260 
00261     void w( F ) ;
00262     void x( F ) ;
00263     void y( F ) ;
00264     void z( F ) ;
00265 
00266     quat & operator+=( const quat & ) ;
00267     quat & operator+=( const pure<F> & ) ;
00268     quat & operator+=( F ) ;
00269 
00270     quat & operator-=( const quat & ) ;
00271     quat & operator-=( const pure<F> & ) ;
00272     quat & operator-=( F ) ;
00273 
00274     quat & operator*=( const quat & ) ;
00275     quat & operator*=( const pure<F> & ) ;
00276     quat & operator*=( F ) ;
00277 
00278     quat & operator/=( F ) ;
00279 
00280     const F* data() const ;
00281 
00282 private:
00283     F mx ;
00284     F my ;
00285     F mz ;
00286     F mw ;
00287 } ;
00288 
00289 template< typename F >
00290 class pure
00291 {
00292 public:
00293     typedef F value_type ;
00294 
00295     pure() ;
00296     pure( F x, F y, F z ) ;
00297 
00298     F w() const ;
00299     F x() const ;
00300     F y() const ;
00301     F z() const ;
00302 
00303     void x( F ) ;
00304     void y( F ) ;
00305     void z( F ) ;
00306 
00307     pure & operator+=( const pure & ) ;
00308     pure & operator-=( const pure & ) ;
00309     pure & operator*=( F ) ;
00310     pure & operator/=( F ) ;
00311 
00312     const F* data() const ;
00313 
00314 private:
00315     F mx ;
00316     F my ;
00317     F mz ;
00318 } ;
00319 
00321 //
00322 // nonmember functions
00323 //
00325 
00327 // realpart
00329 
00330 template< typename F >
00331 inline
00332 F realpart( const quat<F> & a )
00333 {
00334     return a.w() ;
00335 }
00336 
00337 template< typename F >
00338 inline
00339 F realpart( const pure<F> & a )
00340 {
00341     return F() ;
00342 }
00343 
00345 // purepart
00347 
00348 template< typename F >
00349 inline
00350 const pure<F> purepart( const quat<F> & a )
00351 {
00352     return pure<F>(a.x(), a.y(), a.z()) ;
00353 }
00354 
00355 template< typename F >
00356 inline
00357 const pure<F> & purepart( const pure<F> & a )
00358 {
00359     return a ;
00360 }
00361 
00363 // norm
00365 
00366 template< typename F >
00367 inline
00368 F norm( const quat<F> & a )
00369 {
00370     return
00371         a.w()*a.w() +
00372         a.x()*a.x() +
00373         a.y()*a.y() +
00374         a.z()*a.z() ;
00375 }
00376 
00377 template< typename F >
00378 inline
00379 F norm( const pure<F> & a )
00380 {
00381     return
00382         a.x()*a.x() +
00383         a.y()*a.y() +
00384         a.z()*a.z() ;
00385 }
00386 
00388 // abs
00390 
00391 template< typename F >
00392 inline
00393 F abs( const quat<F> & a )
00394 {
00395     return scalar_func::sqrt(norm(a)) ;
00396 }
00397 
00398 template< typename F >
00399 inline
00400 F abs( const pure<F> & a )
00401 {
00402     return scalar_func::sqrt(norm(a)) ;
00403 }
00404 
00406 // exp
00408 
00409 template< typename F >
00410 quat<F> exp( const quat<F> & a )
00411 {
00412     const pure<F> purepart_a = purepart(a) ;
00413 
00414     if( purepart_a == pure<F>() )
00415     {
00416         return quat<F>(scalar_func::exp(realpart(a))) ;
00417     }
00418 
00419     const F abs_purepart_a = abs(purepart_a) ;
00420     const F exp_realpart_a = scalar_func::exp(realpart(a)) ;
00421 
00422     return
00423         quat<F>(exp_realpart_a
00424                 *
00425                 scalar_func::cos(abs_purepart_a),
00426 
00427                 (
00428                  exp_realpart_a
00429                  *
00430                  scalar_func::sin(abs_purepart_a)
00431                  /
00432                  abs_purepart_a
00433                  )
00434                 *
00435                 purepart_a) ;
00436 }
00437 
00438 template< typename F >
00439 inline
00440 quat<F> exp( const pure<F> & a )
00441 {
00442     return exp(quat<F>(a)) ;
00443 }
00444 
00446 // natural log
00448 
00449 template< typename F >
00450 quat<F> log( const quat<F> & a )
00451 {
00452     const pure<F> purepart_a = purepart(a) ;
00453 
00454     if( purepart_a == pure<F>() )
00455     {
00456         return quat<F>(scalar_func::log(realpart(a))) ;
00457     }
00458 
00459     const F abs_purepart_a = abs(purepart_a) ;
00460 
00461     return
00462         quat<F>(scalar_func::log(abs(a)),
00463 
00464                 (scalar_func::atan2(abs_purepart_a, realpart(a))
00465                  /
00466                  abs_purepart_a)
00467                 *
00468                 purepart_a) ;
00469 }
00470 
00471 template< typename F >
00472 inline
00473 quat<F> log( const pure<F> & a )
00474 {
00475     return log(quat<F>(a)) ;
00476 }
00477 
00479 // trig
00481 
00482 template< typename F >
00483 quat<F> cos( const quat<F> & a )
00484 {
00485     const pure<F> purepart_a = purepart(a) ;
00486 
00487     if( purepart_a == pure<F>() )
00488     {
00489         return quat<F>(scalar_func::cos(realpart(a))) ;
00490     }
00491 
00492     const F abs_purepart_a = abs(purepart_a) ;
00493 
00494     // (exp(u*a) + exp(-u*a))/2
00495     return quat<F>(scalar_func::cos(realpart(a))
00496                    *
00497                    scalar_func::cosh(abs_purepart_a),
00498 
00499                    (
00500                     -scalar_func::sin(realpart(a))
00501                     *
00502                     scalar_func::sinh(abs_purepart_a)
00503                     /
00504                     abs_purepart_a
00505                     )
00506                    *
00507                    purepart_a) ;
00508 }
00509 
00510 template< typename F >
00511 quat<F> sin( const quat<F> & a )
00512 {
00513     const pure<F> purepart_a = purepart(a) ;
00514 
00515     if( purepart_a == pure<F>() )
00516     {
00517         return quat<F>(scalar_func::sin(realpart(a))) ;
00518     }
00519 
00520     const F abs_purepart_a = abs(purepart_a) ;
00521 
00522     // inv(u)*(exp(u*a) - exp(-u*a))/2
00523     return quat<F>(scalar_func::sin(realpart(a))
00524                    *
00525                    scalar_func::cosh(abs_purepart_a),
00526 
00527                    (
00528                     scalar_func::cos(realpart(a))
00529                     *
00530                     scalar_func::sinh(abs_purepart_a)
00531                     /
00532                     abs_purepart_a
00533                     )
00534                    *
00535                    purepart_a) ;
00536 }
00537 
00538 template< typename F >
00539 quat<F> tan( const quat<F> & a )
00540 {
00541     return sin(a)*inv(cos(a)) ;
00542 }
00543 
00544 template< typename F >
00545 quat<F> cosh( const quat<F> & a )
00546 {
00547     const pure<F> purepart_a = purepart(a) ;
00548 
00549     if( purepart_a == pure<F>() )
00550     {
00551         return quat<F>(scalar_func::cosh(realpart(a))) ;
00552     }
00553 
00554     const F abs_purepart_a = abs(purepart_a) ;
00555 
00556     // (exp(a) + exp(-a))/2
00557     return quat<F>(scalar_func::cosh(realpart(a))
00558                    *
00559                    scalar_func::cos(abs_purepart_a),
00560 
00561                    (
00562                     scalar_func::sinh(realpart(a))
00563                     *
00564                     scalar_func::sin(abs_purepart_a)
00565                     /
00566                     abs_purepart_a
00567                     )
00568                    *
00569                    purepart_a) ;
00570 }
00571 
00572 template< typename F >
00573 quat<F> sinh( const quat<F> & a )
00574 {
00575     const pure<F> purepart_a = purepart(a) ;
00576 
00577     if( purepart_a == pure<F>() )
00578     {
00579         return quat<F>(scalar_func::sinh(realpart(a))) ;
00580     }
00581 
00582     const F abs_purepart_a = abs(purepart_a) ;
00583 
00584     // (exp(a) - exp(-a))/2
00585     return quat<F>(scalar_func::sinh(realpart(a))
00586                    *
00587                    scalar_func::cos(abs_purepart_a),
00588 
00589                    (
00590                     scalar_func::cosh(realpart(a))
00591                     *
00592                     scalar_func::sin(abs_purepart_a)
00593                     /
00594                     abs_purepart_a
00595                     )
00596                    *
00597                    purepart_a) ;
00598 }
00599 
00600 template< typename F >
00601 quat<F> tanh( const quat<F> & a )
00602 {
00603     return sinh(a)*inv(cosh(a)) ;
00604 }
00605 
00606 template< typename F >
00607 inline
00608 quat<F> cos( const pure<F> & a )
00609 {
00610     return cos(quat<F>(a)) ;
00611 }
00612 
00613 template< typename F >
00614 inline
00615 quat<F> sin( const pure<F> & a )
00616 {
00617     return sin(quat<F>(a)) ;
00618 }
00619 
00620 template< typename F >
00621 inline
00622 quat<F> tan( const pure<F> & a )
00623 {
00624     return tan(quat<F>(a)) ;
00625 }
00626 
00627 template< typename F >
00628 inline
00629 quat<F> cosh( const pure<F> & a )
00630 {
00631     return cosh(quat<F>(a)) ;
00632 }
00633 
00634 template< typename F >
00635 inline
00636 quat<F> sinh( const pure<F> & a )
00637 {
00638     return sinh(quat<F>(a)) ;
00639 }
00640 
00641 template< typename F >
00642 inline
00643 quat<F> tanh( const pure<F> & a )
00644 {
00645     return tanh(quat<F>(a)) ;
00646 }
00647 
00649 // pow
00651 
00652 template< typename F >
00653 quat<F> pow( const quat<F> & a, F gamma )
00654 {
00655     const pure<F> purepart_a = purepart(a) ;
00656 
00657     if( purepart_a == pure<F>() )
00658     {
00659         return quat<F>(scalar_func::pow(realpart(a), gamma)) ;
00660     }
00661 
00662     const F abs_purepart_a = abs(purepart_a) ;
00663     const F theta = scalar_func::atan2(abs_purepart_a, realpart(a)) ;
00664     const F pow_abs_a_gamma = scalar_func::pow(abs(a), gamma) ;
00665 
00666     return
00667         quat<F>(scalar_func::cos(gamma*theta)
00668                 *
00669                 pow_abs_a_gamma,
00670 
00671                 (scalar_func::sin(gamma*theta)
00672                  *
00673                  pow_abs_a_gamma
00674                  /
00675                  abs_purepart_a)
00676                 *
00677                 purepart_a) ;
00678 }
00679 
00680 template< typename F >
00681 quat<F> pow( const quat<F> & a, unsigned int n )
00682 {
00683     quat<F> b = (n % 2) ? a : quat<F>(F(1)) ;
00684     quat<F> c = a ;
00685 
00686     while( n >>= 1 )
00687     {
00688         c = c*c ;
00689         if( n % 2 == 1 )
00690         {
00691             b = c*b ;
00692         }
00693     }
00694 
00695     return b ;
00696 }
00697 
00698 template< typename F >
00699 inline
00700 quat<F> pow( const quat<F> & a, int n )
00701 {
00702     typedef unsigned int uint ;
00703 
00704     return n >= 0 ? pow(a, uint(n)) : inv(pow(a, uint(-n))) ;
00705 }
00706 
00707 template< typename F >
00708 inline
00709 quat<F> pow( F gamma, const quat<F> & a )
00710 {
00711     return gamma == F() ? quat<F>(F()) : exp(scalar_func::log(gamma)*a) ;
00712 }
00713 
00714 template< typename F >
00715 inline
00716 quat<F> pow( const pure<F> & a, F r )
00717 {
00718     return pow(quat<F>(a), r) ;
00719 }
00720 
00721 template< typename F >
00722 quat<F> pow( const pure<F> & a, unsigned int n )
00723 {
00724     switch( n % 4 )
00725     {
00726     case 0:
00727         return quat<F>(scalar_func::pow(norm(a), int(n/2))) ;
00728     case 1:
00729         return quat<F>(a*scalar_func::pow(norm(a), int(n/2))) ;
00730     case 2:
00731         return quat<F>(-scalar_func::pow(norm(a), int(n/2))) ;
00732     case 3:
00733         return quat<F>(a*(-scalar_func::pow(norm(a), int(n/2)))) ;
00734     }
00735 
00736     return quat<F>() ;
00737 }
00738 
00739 template< typename F >
00740 quat<F> pow( const pure<F> & a, int n )
00741 {
00742     typedef unsigned int uint ;
00743 
00744     if( n >= 0 )
00745     {
00746         return pow(a, uint(n)) ;
00747     }
00748 
00749     switch( (-n) % 4 )
00750     {
00751     case 0:
00752         return quat<F>(scalar_func::pow(norm(a), int(n/2))) ;
00753     case 1:
00754         return quat<F>(a*(-scalar_func::pow(norm(a), int(n/2) - 1))) ;
00755     case 2:
00756         return quat<F>(-scalar_func::pow(norm(a), int(n/2))) ;
00757     case 3:
00758         return quat<F>(a*(scalar_func::pow(norm(a), int(n/2) - 1))) ;
00759     }
00760 
00761     return quat<F>() ;
00762 }
00763 
00764 template< typename F >
00765 inline
00766 quat<F> pow( F gamma, const pure<F> & a )
00767 {
00768     return pow(gamma, quat<F>(a)) ;
00769 }
00770 
00772 // sqrt
00774 
00775 template< typename F >
00776 inline
00777 quat<F> sqrt( const quat<F> & a )
00778 {
00779     return pow(a, F(0.5)) ;
00780 }
00781 
00782 template< typename F >
00783 inline
00784 quat<F> sqrt( const pure<F> & a )
00785 {
00786     return pow(quat<F>(a), F(0.5)) ;
00787 }
00788 
00790 // conj
00792 
00793 template< typename F >
00794 inline
00795 quat<F> conj( const quat<F> & a )
00796 {
00797     return quat<F>( a.w(),
00798                    -a.x(),
00799                    -a.y(),
00800                    -a.z()) ;
00801 }
00802 
00803 template< typename F >
00804 inline
00805 pure<F> conj( const pure<F> & a )
00806 {
00807     return pure<F>(-a.x(),
00808                    -a.y(),
00809                    -a.z()) ;
00810 }
00811 
00813 // inv
00815 
00816 template< typename F >
00817 inline
00818 quat<F> inv( const quat<F> & a )
00819 {
00820     const F neg_norm_a =
00821         -(a.w()*a.w() +
00822           a.x()*a.x() +
00823           a.y()*a.y() +
00824           a.z()*a.z()) ;
00825 
00826     return quat<F>(-a.w()/neg_norm_a,
00827                     a.x()/neg_norm_a,
00828                     a.y()/neg_norm_a,
00829                     a.z()/neg_norm_a) ;
00830 }
00831 
00832 template< typename F >
00833 inline
00834 pure<F> inv( const pure<F> & a )
00835 {
00836     const F neg_norm_a =
00837         -(a.x()*a.x() +
00838           a.y()*a.y() +
00839           a.z()*a.z()) ;
00840 
00841     return pure<F>(a.x()/neg_norm_a,
00842                    a.y()/neg_norm_a,
00843                    a.z()/neg_norm_a) ;
00844 }
00845 
00847 // dot
00849 
00850 template< typename F >
00851 inline
00852 F dot( const quat<F> & a, const quat<F> & b )
00853 {
00854     return
00855         a.w()*b.w() +
00856         a.x()*b.x() +
00857         a.y()*b.y() +
00858         a.z()*b.z() ;
00859 }
00860 
00861 template< typename F >
00862 inline
00863 F dot( const pure<F> & a, const quat<F> & b )
00864 {
00865     return
00866         a.x()*b.x() +
00867         a.y()*b.y() +
00868         a.z()*b.z() ;
00869 }
00870 
00871 template< typename F >
00872 inline
00873 F dot( const quat<F> & a, const pure<F> & b )
00874 {
00875     return
00876         a.x()*b.x() +
00877         a.y()*b.y() +
00878         a.z()*b.z() ;
00879 }
00880 
00881 template< typename F >
00882 inline
00883 F dot( const pure<F> & a, const pure<F> & b )
00884 {
00885     return
00886         a.x()*b.x() +
00887         a.y()*b.y() +
00888         a.z()*b.z() ;
00889 }
00890 
00891 template< typename F >
00892 inline
00893 F dot( F a, const quat<F> & b )
00894 {
00895     return a*b.w() ;
00896 }
00897 
00898 template< typename F >
00899 inline
00900 F dot( const quat<F> & a, F b )
00901 {
00902     return a.w()*b ;
00903 }
00904 
00905 template< typename F >
00906 inline
00907 F dot( F, const pure<F> & )
00908 {
00909     return F() ;
00910 }
00911 
00912 template< typename F >
00913 inline
00914 F dot( const pure<F> &, F )
00915 {
00916     return F() ;
00917 }
00918 
00920 // cross
00922 
00923 template< typename F >
00924 inline
00925 pure<F> cross( const quat<F> & a, const quat<F> & b )
00926 {
00927     return pure<F>(a.w()*b.x() - a.x()*b.w() + a.y()*b.z() - a.z()*b.y(),
00928                    a.w()*b.y() - a.y()*b.w() + a.z()*b.x() - a.x()*b.z(),
00929                    a.w()*b.z() - a.z()*b.w() + a.x()*b.y() - a.y()*b.x()) ;
00930 }
00931 
00932 template< typename F >
00933 inline
00934 pure<F> cross( const quat<F> & a, const pure<F> & b )
00935 {
00936     return pure<F>(a.w()*b.x() + a.y()*b.z() - a.z()*b.y(),
00937                    a.w()*b.y() + a.z()*b.x() - a.x()*b.z(),
00938                    a.w()*b.z() + a.x()*b.y() - a.y()*b.x()) ;
00939 }
00940 
00941 template< typename F >
00942 inline
00943 pure<F> cross( const pure<F> & a, const quat<F> & b )
00944 {
00945     return pure<F>(a.y()*b.z() - a.x()*b.w() - a.z()*b.y(),
00946                    a.z()*b.x() - a.y()*b.w() - a.x()*b.z(),
00947                    a.x()*b.y() - a.z()*b.w() - a.y()*b.x()) ;
00948 }
00949 
00950 template< typename F >
00951 inline
00952 pure<F> cross( const pure<F> & a, const pure<F> & b )
00953 {
00954     return pure<F>(a.y()*b.z() - a.z()*b.y(),
00955                    a.z()*b.x() - a.x()*b.z(),
00956                    a.x()*b.y() - a.y()*b.x()) ;
00957 }
00958 
00959 template< typename F >
00960 inline
00961 pure<F> cross( F a, const quat<F> & b )
00962 {
00963     return pure<F>(a*b.x(),
00964                    a*b.y(),
00965                    a*b.z()) ;
00966 }
00967 
00968 template< typename F >
00969 inline
00970 pure<F> cross( const quat<F> & a, F b )
00971 {
00972     return pure<F>(-a.x()*b,
00973                    -a.y()*b,
00974                    -a.z()*b) ;
00975 }
00976 
00977 template< typename F >
00978 inline
00979 pure<F> cross( F a, const pure<F> & b )
00980 {
00981     return pure<F>(a*b.x(),
00982                    a*b.y(),
00983                    a*b.z()) ;
00984 }
00985 
00986 template< typename F >
00987 inline
00988 pure<F> cross( const pure<F> & a, F b )
00989 {
00990     return pure<F>(-a*b.x(),
00991                    -a*b.y(),
00992                    -a*b.z()) ;
00993 }
00994 
00996 // operator==
00998 
00999 template< typename F >
01000 inline
01001 bool operator==( const quat<F> & a, const quat<F> & b )
01002 {
01003     return
01004         a.w() == b.w() &&
01005         a.x() == b.x() &&
01006         a.y() == b.y() &&
01007         a.z() == b.z() ;
01008 }
01009 
01010 template< typename F >
01011 inline
01012 bool operator==( const quat<F> & a, const pure<F> & b )
01013 {
01014     return
01015         a.w() == F() &&
01016         a.x() == b.x() &&
01017         a.y() == b.y() &&
01018         a.z() == b.z() ;
01019 }
01020 
01021 template< typename F >
01022 inline
01023 bool operator==( const pure<F> & a, const quat<F> & b )
01024 {
01025     return
01026         F()   == b.w() &&
01027         a.x() == b.x() &&
01028         a.y() == b.y() &&
01029         a.z() == b.z() ;
01030 }
01031 
01032 template< typename F >
01033 inline
01034 bool operator==( const pure<F> & a, const pure<F> & b )
01035 {
01036     return
01037         a.x() == b.x() &&
01038         a.y() == b.y() &&
01039         a.z() == b.z() ;
01040 }
01041 
01042 template< typename F >
01043 inline
01044 bool operator==( F a, const quat<F> & b )
01045 {
01046     return
01047         a   == b.w() &&
01048         F() == b.x() &&
01049         F() == b.y() &&
01050         F() == b.z() ;
01051 }
01052 
01053 template< typename F >
01054 inline
01055 bool operator==( F a, const pure<F> & b )
01056 {
01057     return
01058         a   == F() &&
01059         F() == b.x() &&
01060         F() == b.y() &&
01061         F() == b.z() ;
01062 }
01063 
01064 template< typename F >
01065 inline
01066 bool operator==( const quat<F> & a, F b )
01067 {
01068     return
01069         a.w() == b &&
01070         a.x() == F() &&
01071         a.y() == F() &&
01072         a.z() == F() ;
01073 }
01074 
01075 template< typename F >
01076 inline
01077 bool operator==( const pure<F> & a, F b )
01078 {
01079     return
01080         F()   == b &&
01081         a.x() == F() &&
01082         a.y() == F() &&
01083         a.z() == F() ;
01084 }
01085 
01087 // operator!=
01089 
01090 template< typename F >
01091 inline
01092 bool operator!=( const quat<F> & a, const quat<F> & b )
01093 {
01094     return !(a == b) ;
01095 }
01096 
01097 template< typename F >
01098 inline
01099 bool operator!=( const quat<F> & a, const pure<F> & b )
01100 {
01101     return !(a == b) ;
01102 }
01103 
01104 template< typename F >
01105 inline
01106 bool operator!=( const pure<F> & a, const quat<F> & b )
01107 {
01108     return !(a == b) ;
01109 }
01110 
01111 template< typename F >
01112 inline
01113 bool operator!=( const pure<F> & a, const pure<F> & b )
01114 {
01115     return !(a == b) ;
01116 }
01117 
01118 template< typename F >
01119 inline
01120 bool operator!=( const quat<F> & a, F b )
01121 {
01122     return !(a == b) ;
01123 }
01124 
01125 template< typename F >
01126 inline
01127 bool operator!=( const pure<F> & a, F b )
01128 {
01129     return !(a == b) ;
01130 }
01131 
01132 template< typename F >
01133 inline
01134 bool operator!=( F a, const quat<F> & b )
01135 {
01136     return !(a == b) ;
01137 }
01138 
01139 template< typename F >
01140 inline
01141 bool operator!=( F a, const pure<F> & b )
01142 {
01143     return !(a == b) ;
01144 }
01145 
01147 // operator+
01149 
01150 template< typename F >
01151 inline
01152 quat<F> operator+( const quat<F> & a, const quat<F> & b )
01153 {
01154     return quat<F>(a.w() + b.w(),
01155                    a.x() + b.x(),
01156                    a.y() + b.y(),
01157                    a.z() + b.z()) ;
01158 }
01159 
01160 template< typename F >
01161 inline
01162 quat<F> operator+( const quat<F> & a, const pure<F> & b )
01163 {
01164     return quat<F>(a.w(),
01165                    a.x() + b.x(),
01166                    a.y() + b.y(),
01167                    a.z() + b.z()) ;
01168 }
01169 
01170 template< typename F >
01171 inline
01172 quat<F> operator+( const pure<F> & a, const quat<F> & b )
01173 {
01174     return quat<F>(        b.w(),
01175                    a.x() + b.x(),
01176                    a.y() + b.y(),
01177                    a.z() + b.z()) ;
01178 }
01179 
01180 template< typename F >
01181 inline
01182 pure<F> operator+( const pure<F> & a, const pure<F> & b )
01183 {
01184     return pure<F>(a.x() + b.x(),
01185                    a.y() + b.y(),
01186                    a.z() + b.z()) ;
01187 }
01188 
01189 template< typename F >
01190 inline
01191 quat<F> operator+( F a, const quat<F> & b )
01192 {
01193     return quat<F>(a + b.w(),
01194                        b.x(),
01195                        b.y(),
01196                        b.z()) ;
01197 }
01198 
01199 template< typename F >
01200 inline
01201 quat<F> operator+( F a, const pure<F> & b )
01202 {
01203     return quat<F>(a,
01204                        b.x(),
01205                        b.y(),
01206                        b.z()) ;
01207 }
01208 
01209 template< typename F >
01210 inline
01211 quat<F> operator+( const quat<F> & a, F b )
01212 {
01213     return quat<F>(a.w() + b,
01214                    a.x(),
01215                    a.y(),
01216                    a.z()) ;
01217 }
01218 
01219 template< typename F >
01220 inline
01221 quat<F> operator+( const pure<F> & a, F b )
01222 {
01223     return quat<F>(b,
01224                    a.x(),
01225                    a.y(),
01226                    a.z()) ;
01227 }
01228 
01229 template< typename F >
01230 inline
01231 const quat<F> & operator+( const quat<F> & a )
01232 {
01233     return a ;
01234 }
01235 
01236 template< typename F >
01237 inline
01238 const pure<F> & operator+( const pure<F> & a )
01239 {
01240     return a ;
01241 }
01242 
01244 // operator-
01246 
01247 template< typename F >
01248 inline
01249 quat<F> operator-( const quat<F> & a, const quat<F> & b )
01250 {
01251     return quat<F>(a.w() - b.w(),
01252                    a.x() - b.x(),
01253                    a.y() - b.y(),
01254                    a.z() - b.z()) ;
01255 }
01256 
01257 template< typename F >
01258 inline
01259 quat<F> operator-( const quat<F> & a, const pure<F> & b )
01260 {
01261     return quat<F>(a.w(),
01262                    a.x() - b.x(),
01263                    a.y() - b.y(),
01264                    a.z() - b.z()) ;
01265 }
01266 
01267 template< typename F >
01268 inline
01269 quat<F> operator-( const pure<F> & a, const quat<F> & b )
01270 {
01271     return quat<F>(      - b.w(),
01272                    a.x() - b.x(),
01273                    a.y() - b.y(),
01274                    a.z() - b.z()) ;
01275 }
01276 
01277 template< typename F >
01278 inline
01279 pure<F> operator-( const pure<F> & a, const pure<F> & b )
01280 {
01281     return pure<F>(a.x() - b.x(),
01282                    a.y() - b.y(),
01283                    a.z() - b.z()) ;
01284 }
01285 
01286 template< typename F >
01287 inline
01288 quat<F> operator-( F a, const quat<F> & b )
01289 {
01290     return quat<F>(a - b.w(),
01291                      - b.x(),
01292                      - b.y(),
01293                      - b.z()) ;
01294 }
01295 
01296 template< typename F >
01297 inline
01298 quat<F> operator-( F a, const pure<F> & b )
01299 {
01300     return quat<F>(a,
01301                      - b.x(),
01302                      - b.y(),
01303                      - b.z()) ;
01304 }
01305 
01306 template< typename F >
01307 inline
01308 quat<F> operator-( const quat<F> & a, F b )
01309 {
01310     return quat<F>(a.w() - b,
01311                    a.x(),
01312                    a.y(),
01313                    a.z()) ;
01314 }
01315 
01316 template< typename F >
01317 inline
01318 quat<F> operator-( const pure<F> & a, F b )
01319 {
01320     return quat<F>(-b,
01321                    a.x(),
01322                    a.y(),
01323                    a.z()) ;
01324 }
01325 
01326 template< typename F >
01327 inline
01328 quat<F> operator-( const quat<F> & a )
01329 {
01330     return quat<F>(-a.w(),
01331                    -a.x(),
01332                    -a.y(),
01333                    -a.z()) ;
01334 }
01335 
01336 template< typename F >
01337 inline
01338 pure<F> operator-( const pure<F> & a )
01339 {
01340     return pure<F>(-a.x(),
01341                    -a.y(),
01342                    -a.z()) ;
01343 }
01344 
01346 // operator*
01348 
01349 #if !defined(QUAT_CONSERVE_MULTIPLIES)
01350 template< typename F >
01351 inline
01352 quat<F> operator*( const quat<F> & a, const quat<F> & b )
01353 {
01354     return quat<F>(a.w()*b.w() - a.x()*b.x() - a.y()*b.y() - a.z()*b.z(),
01355                    a.w()*b.x() + a.x()*b.w() + a.y()*b.z() - a.z()*b.y(),
01356                    a.w()*b.y() - a.x()*b.z() + a.y()*b.w() + a.z()*b.x(),
01357                    a.w()*b.z() + a.x()*b.y() - a.y()*b.x() + a.z()*b.w()) ;
01358 }
01359 #endif
01360 
01361 #if defined(QUAT_CONSERVE_MULTIPLIES)
01362 template< typename F >
01363 quat<F> operator*( const quat<F> & a, const quat<F> & b )
01364 {
01365     const F a1 =  (a.z() - a.y())*(b.y() - b.z()) ;
01366     const F a2 =  (a.w() + a.x())*(b.w() + b.x()) ;
01367     const F a3 =  (a.w() - a.x())*(b.y() + b.z()) ;
01368     const F a4 =  (a.y() + a.z())*(b.w() - b.x()) ;
01369 
01370     const F b1 =  (a.z() - a.x())*(b.x() - b.y()) ;
01371     const F b2 = -(a.x() + a.z())*(b.x() + b.y()) ;
01372     const F b3 =  (a.w() + a.y())*(b.w() - b.z()) ;
01373     const F b4 =  (a.w() - a.y())*(b.w() + b.z()) ;
01374 
01375     return quat<F>(a1 + F(0.5)*(b1 + b2 + b3 + b4),
01376                    a2 + F(0.5)*(b1 + b2 - b3 - b4),
01377                    a3 + F(0.5)*(b1 - b2 + b3 - b4),
01378                    a4 + F(0.5)*(b1 - b2 - b3 + b4)) ;
01379 }
01380 #endif
01381 
01382 template< typename F >
01383 inline
01384 quat<F> operator*( const quat<F> & a, const pure<F> & b )
01385 {
01386     return quat<F>(- a.x()*b.x() - a.y()*b.y() - a.z()*b.z(),
01387                      a.w()*b.x() + a.y()*b.z() - a.z()*b.y(),
01388                      a.w()*b.y() - a.x()*b.z() + a.z()*b.x(),
01389                      a.w()*b.z() + a.x()*b.y() - a.y()*b.x()) ;
01390 }
01391 
01392 template< typename F >
01393 inline
01394 quat<F> operator*( const pure<F> & a, const quat<F> & b )
01395 {
01396     return quat<F>(- a.x()*b.x() - a.y()*b.y() - a.z()*b.z(),
01397                      a.x()*b.w() + a.y()*b.z() - a.z()*b.y(),
01398                      a.y()*b.w() + a.z()*b.x() - a.x()*b.z(),
01399                      a.x()*b.y() - a.y()*b.x() + a.z()*b.w()) ;
01400 }
01401 
01402 template< typename F >
01403 inline
01404 quat<F> operator*( const pure<F> & a, const pure<F> & b )
01405 {
01406     return quat<F>(- a.x()*b.x() - a.y()*b.y() - a.z()*b.z(),
01407                      a.y()*b.z() - a.z()*b.y(),
01408                      a.z()*b.x() - a.x()*b.z(),
01409                      a.x()*b.y() - a.y()*b.x()) ;
01410 }
01411 
01412 template< typename F >
01413 inline
01414 quat<F> operator*( F a, const quat<F> & b )
01415 {
01416     return quat<F>(a*b.w(),
01417                    a*b.x(),
01418                    a*b.y(),
01419                    a*b.z()) ;
01420 }
01421 
01422 template< typename F >
01423 inline
01424 pure<F> operator*( F a, const pure<F> & b )
01425 {
01426     return pure<F>(a*b.x(),
01427                    a*b.y(),
01428                    a*b.z()) ;
01429 }
01430 
01431 template< typename F >
01432 inline
01433 quat<F> operator*( const quat<F> & a, F b )
01434 {
01435     return quat<F>(a.w()*b,
01436                    a.x()*b,
01437                    a.y()*b,
01438                    a.z()*b) ;
01439 }
01440 
01441 template< typename F >
01442 inline
01443 pure<F> operator*( const pure<F> & a, F b )
01444 {
01445     return pure<F>(a.x()*b,
01446                    a.y()*b,
01447                    a.z()*b) ;
01448 }
01449 
01451 // operator/
01453 
01454 template< typename F >
01455 inline
01456 quat<F> operator/( const quat<F> & a, F b )
01457 {
01458     return quat<F>(a.w()/b,
01459                    a.x()/b,
01460                    a.y()/b,
01461                    a.z()/b) ;
01462 }
01463 
01464 template< typename F >
01465 inline
01466 pure<F> operator/( const pure<F> & a, F b )
01467 {
01468     return pure<F>(a.x()/b,
01469                    a.y()/b,
01470                    a.z()/b) ;
01471 }
01472 
01474 //
01475 // quat member functions
01476 //
01478 
01480 // constructors
01482 
01483 template< typename F >
01484 inline
01485 quat<F>::
01486 quat()
01487     : mx(F()),
01488       my(F()),
01489       mz(F()),
01490       mw(F())
01491 {
01492 }
01493 
01494 template< typename F >
01495 inline
01496 quat<F>::
01497 quat( F w, F x, F y, F z )
01498     : mx(x),
01499       my(y),
01500       mz(z),
01501       mw(w)
01502 {
01503 }
01504 
01505 template< typename F >
01506 inline
01507 quat<F>::
01508 quat( F w, const pure<F> & a )
01509     : mx(a.x()),
01510       my(a.y()),
01511       mz(a.z()),
01512       mw(w)
01513 {
01514 }
01515 
01516 template< typename F >
01517 inline
01518 quat<F>::
01519 quat( const pure<F> & a )
01520     : mx(a.x()),
01521       my(a.y()),
01522       mz(a.z()),
01523       mw(F())
01524 {
01525 }
01526 
01527 template< typename F >
01528 inline
01529 quat<F>::
01530 quat( F w )
01531     : mx(F()),
01532       my(F()),
01533       mz(F()),
01534       mw(w)
01535 {
01536 }
01537 
01539 // readers
01541 
01542 template< typename F >
01543 inline
01544 F
01545 quat<F>::
01546 w() const
01547 {
01548     return mw ;
01549 }
01550 
01551 template< typename F >
01552 inline
01553 F
01554 quat<F>::
01555 x() const
01556 {
01557     return mx ;
01558 }
01559 
01560 template< typename F >
01561 inline
01562 F
01563 quat<F>::
01564 y() const
01565 {
01566     return my ;
01567 }
01568 
01569 template< typename F >
01570 inline
01571 F
01572 quat<F>::
01573 z() const
01574 {
01575     return mz ;
01576 }
01577 
01579 // writers
01581 
01582 template< typename F >
01583 inline
01584 void
01585 quat<F>::
01586 w( F a )
01587 {
01588     mw = a ;
01589 }
01590 
01591 template< typename F >
01592 inline
01593 void
01594 quat<F>::
01595 x( F a )
01596 {
01597     mx = a ;
01598 }
01599 
01600 template< typename F >
01601 inline
01602 void
01603 quat<F>::
01604 y( F a )
01605 {
01606     my = a ;
01607 }
01608 
01609 template< typename F >
01610 inline
01611 void
01612 quat<F>::
01613 z( F a )
01614 {
01615     mz = a ;
01616 }
01617 
01619 // operator+=
01621 
01622 template< typename F >
01623 inline
01624 quat<F> &
01625 quat<F>::
01626 operator+=( const quat & a )
01627 {
01628     mw += a.w() ;
01629     mx += a.x() ;
01630     my += a.y() ;
01631     mz += a.z() ;
01632     return *this ;
01633 }
01634 
01635 template< typename F >
01636 inline
01637 quat<F> &
01638 quat<F>::
01639 operator+=( const pure<F> & a )
01640 {
01641     mx += a.x() ;
01642     my += a.y() ;
01643     mz += a.z() ;
01644     return *this ;
01645 }
01646 
01647 template< typename F >
01648 inline
01649 quat<F> &
01650 quat<F>::
01651 operator+=( F a )
01652 {
01653     mw += a ;
01654     return *this ;
01655 }
01656 
01658 // operator-=
01660 
01661 template< typename F >
01662 inline
01663 quat<F> &
01664 quat<F>::
01665 operator-=( const quat & a )
01666 {
01667     mw -= a.w() ;
01668     mx -= a.x() ;
01669     my -= a.y() ;
01670     mz -= a.z() ;
01671     return *this ;
01672 }
01673 
01674 template< typename F >
01675 inline
01676 quat<F> &
01677 quat<F>::
01678 operator-=( const pure<F> & a )
01679 {
01680     mx -= a.x() ;
01681     my -= a.y() ;
01682     mz -= a.z() ;
01683     return *this ;
01684 }
01685 
01686 template< typename F >
01687 inline
01688 quat<F> &
01689 quat<F>::
01690 operator-=( F a )
01691 {
01692     mw -= a ;
01693     return *this ;
01694 }
01695 
01697 // operator*=
01699 
01700 #if !defined(QUAT_CONSERVE_MULTIPLIES)
01701 template< typename F >
01702 inline
01703 quat<F> &
01704 quat<F>::
01705 operator*=( const quat & b )
01706 {
01707     const quat a = *this ;
01708     mw = a.w()*b.w() - a.x()*b.x() - a.y()*b.y() - a.z()*b.z() ;
01709     mx = a.w()*b.x() + a.x()*b.w() + a.y()*b.z() - a.z()*b.y() ;
01710     my = a.w()*b.y() - a.x()*b.z() + a.y()*b.w() + a.z()*b.x() ;
01711     mz = a.w()*b.z() + a.x()*b.y() - a.y()*b.x() + a.z()*b.w() ;
01712     return *this ;
01713 }
01714 #endif
01715 
01716 #if defined(QUAT_CONSERVE_MULTIPLIES)
01717 template< typename F >
01718 quat<F> &
01719 quat<F>::
01720 operator*=( const quat & b )
01721 {
01722     const quat a = *this ;
01723 
01724     const F a1 =  (a.z() - a.y())*(b.y() - b.z()) ;
01725     const F a2 =  (a.w() + a.x())*(b.w() + b.x()) ;
01726     const F a3 =  (a.w() - a.x())*(b.y() + b.z()) ;
01727     const F a4 =  (a.y() + a.z())*(b.w() - b.x()) ;
01728 
01729     const F b1 =  (a.z() - a.x())*(b.x() - b.y()) ;
01730     const F b2 = -(a.x() + a.z())*(b.x() + b.y()) ;
01731     const F b3 =  (a.w() + a.y())*(b.w() - b.z()) ;
01732     const F b4 =  (a.w() - a.y())*(b.w() + b.z()) ;
01733 
01734     mw = a1 + F(0.5)*(b1 + b2 + b3 + b4) ;
01735     mx = a2 + F(0.5)*(b1 + b2 - b3 - b4) ;
01736     my = a3 + F(0.5)*(b1 - b2 + b3 - b4) ;
01737     mz = a4 + F(0.5)*(b1 - b2 - b3 + b4) ;
01738 
01739     return *this ;
01740 }
01741 #endif
01742 
01743 template< typename F >
01744 inline
01745 quat<F> &
01746 quat<F>::
01747 operator*=( const pure<F> & b )
01748 {
01749     const quat a = *this ;
01750     mw = - a.x()*b.x() - a.y()*b.y() - a.z()*b.z() ;
01751     mx =   a.w()*b.x() + a.y()*b.z() - a.z()*b.y() ;
01752     my =   a.w()*b.y() - a.x()*b.z() + a.z()*b.x() ;
01753     mz =   a.w()*b.z() + a.x()*b.y() - a.y()*b.x() ;
01754     return *this ;
01755 }
01756 
01757 template< typename F >
01758 inline
01759 quat<F> &
01760 quat<F>::
01761 operator*=( F a )
01762 {
01763     mw *= a ;
01764     mx *= a ;
01765     my *= a ;
01766     mz *= a ;
01767     return *this ;
01768 }
01769 
01771 // operator/=
01773 
01774 template< typename F >
01775 inline
01776 quat<F> &
01777 quat<F>::
01778 operator/=( F a )
01779 {
01780     mw /= a ;
01781     mx /= a ;
01782     my /= a ;
01783     mz /= a ;
01784     return *this ;
01785 }
01786 
01788 // data
01790 
01791 template< typename F >
01792 inline
01793 const F*
01794 quat<F>::
01795 data() const
01796 {
01797     return &mx ;
01798 }
01799 
01801 //
01802 // pure member functions
01803 //
01805 
01807 // constructors
01809 
01810 template< typename F >
01811 inline
01812 pure<F>::
01813 pure()
01814     : mx(F()),
01815       my(F()),
01816       mz(F())
01817 {
01818 }
01819 
01820 template< typename F >
01821 inline
01822 pure<F>::
01823 pure( F x, F y, F z )
01824     : mx(x),
01825       my(y),
01826       mz(z)
01827 {
01828 }
01829 
01831 // readers
01833 
01834 template< typename F >
01835 inline
01836 F
01837 pure<F>::
01838 w() const
01839 {
01840     return F() ;
01841 }
01842 
01843 template< typename F >
01844 inline
01845 F
01846 pure<F>::
01847 x() const
01848 {
01849     return mx ;
01850 }
01851 
01852 template< typename F >
01853 inline
01854 F
01855 pure<F>::
01856 y() const
01857 {
01858     return my ;
01859 }
01860 
01861 template< typename F >
01862 inline
01863 F
01864 pure<F>::
01865 z() const
01866 {
01867     return mz ;
01868 }
01869 
01871 // writers
01873 
01874 template< typename F >
01875 inline
01876 void
01877 pure<F>::
01878 x( F a )
01879 {
01880     mx = a ;
01881 }
01882 
01883 template< typename F >
01884 inline
01885 void
01886 pure<F>::
01887 y( F a )
01888 {
01889     my = a ;
01890 }
01891 
01892 template< typename F >
01893 inline
01894 void
01895 pure<F>::
01896 z( F a )
01897 {
01898     mz = a ;
01899 }
01900 
01902 // operators
01904 
01905 template< typename F >
01906 inline
01907 pure<F> &
01908 pure<F>::
01909 operator+=( const pure & a )
01910 {
01911     mx += a.x() ;
01912     my += a.y() ;
01913     mz += a.z() ;
01914     return *this ;
01915 }
01916 
01917 template< typename F >
01918 inline
01919 pure<F> &
01920 pure<F>::
01921 operator-=( const pure & a )
01922 {
01923     mx -= a.x() ;
01924     my -= a.y() ;
01925     mz -= a.z() ;
01926     return *this ;
01927 }
01928 
01929 template< typename F >
01930 inline
01931 pure<F> &
01932 pure<F>::
01933 operator*=( F a )
01934 {
01935     mx *= a ;
01936     my *= a ;
01937     mz *= a ;
01938     return *this ;
01939 }
01940 
01941 template< typename F >
01942 inline
01943 pure<F> &
01944 pure<F>::
01945 operator/=( F a )
01946 {
01947     mx /= a ;
01948     my /= a ;
01949     mz /= a ;
01950     return *this ;
01951 }
01952 
01954 // data
01956 
01957 template< typename F >
01958 inline
01959 const F*
01960 pure<F>::
01961 data() const
01962 {
01963     return &mx ;
01964 }
01965 
01967 // streams
01969 
01970 template< typename F, typename T_Char, typename T_Traits >
01971 std::basic_ostream<T_Char, T_Traits> &
01972 operator<<( std::basic_ostream<T_Char, T_Traits> & out, const quat<F> & a )
01973 {
01974     out << '('
01975         << a.w()
01976         << ','
01977         << a.x()
01978         << ','
01979         << a.y()
01980         << ','
01981         << a.z()
01982         << ')' ;
01983 
01984     return out ;
01985 }
01986 
01987 template< typename F, typename T_Char, typename T_Traits >
01988 std::basic_ostream<T_Char, T_Traits> &
01989 operator<<( std::basic_ostream<T_Char, T_Traits> & out, const pure<F> & a )
01990 {
01991     out << '('
01992         << a.x()
01993         << ','
01994         << a.y()
01995         << ','
01996         << a.z()
01997         << ')' ;
01998 
01999     return out ;
02000 }
02001 
02002 template< typename F, typename T_Char, typename T_Traits >
02003 std::basic_istream<T_Char, T_Traits> &
02004 operator>>( std::basic_istream<T_Char, T_Traits> & in, quat<F> & a )
02005 {
02006     T_Char ch ;
02007     F w ;
02008     F x ;
02009     F y ;
02010     F z ;
02011 
02012     ch = 0 ;
02013     in >> ch ;
02014     if( ch != '(' )
02015     {
02016         in.setstate(std::ios_base::failbit) ;
02017         return in ;
02018     }
02019 
02020     ch = 0 ;
02021     in >> w >> ch ;
02022     if( ch != ',' )
02023     {
02024         in.setstate(std::ios_base::failbit) ;
02025         return in ;
02026     }
02027 
02028     ch = 0 ;
02029     in >> x >> ch ;
02030     if( ch != ',' )
02031     {
02032         in.setstate(std::ios_base::failbit) ;
02033         return in ;
02034     }
02035 
02036     ch = 0 ;
02037     in >> y >> ch ;
02038     if( ch != ',' )
02039     {
02040         in.setstate(std::ios_base::failbit) ;
02041         return in ;
02042     }
02043 
02044     ch = 0 ;
02045     in >> z >> ch ;
02046     if( ch != ')' )
02047     {
02048         in.setstate(std::ios_base::failbit) ;
02049         return in ;
02050     }
02051 
02052     a.w(w) ;
02053     a.x(x) ;
02054     a.y(y) ;
02055     a.z(z) ;
02056 
02057     return in ;
02058 }
02059 
02060 template< typename F, typename T_Char, typename T_Traits >
02061 std::basic_istream<T_Char, T_Traits> &
02062 operator>>( std::basic_istream<T_Char, T_Traits> & in, pure<F> & a )
02063 {
02064     T_Char ch ;
02065     F x ;
02066     F y ;
02067     F z ;
02068 
02069     ch = 0 ;
02070     in >> ch ;
02071     if( ch != '(' )
02072     {
02073         in.setstate(std::ios_base::failbit) ;
02074         return in ;
02075     }
02076 
02077     ch = 0 ;
02078     in >> x >> ch ;
02079     if( ch != ',' )
02080     {
02081         in.setstate(std::ios_base::failbit) ;
02082         return in ;
02083     }
02084 
02085     ch = 0 ;
02086     in >> y >> ch ;
02087     if( ch != ',' )
02088     {
02089         in.setstate(std::ios_base::failbit) ;
02090         return in ;
02091     }
02092 
02093     ch = 0 ;
02094     in >> z >> ch ;
02095     if( ch != ')' )
02096     {
02097         in.setstate(std::ios_base::failbit) ;
02098         return in ;
02099     }
02100 
02101     a.x(x) ;
02102     a.y(y) ;
02103     a.z(z) ;
02104 
02105     return in ;
02106 }
02107 
02109 //
02110 // scalar_func
02111 //
02112 // A new scalar may be introduced by adding the appropriate functions
02113 // to scalar_func (sin, cos, exp, etc.).
02114 //
02115 // The separate namespace also provides the convenience of a 'using'
02116 // directive which pulls in only these functions which do not have a
02117 // class signature.
02118 //
02120 
02121 namespace scalar_func {
02122 
02123 template< typename F >
02124 inline
02125 F realpart( F a )
02126 {
02127     return a ;
02128 }
02129 
02130 template< typename F >
02131 inline
02132 F purepart( F a )
02133 {
02134     return F() ;
02135 }
02136 
02137 template< typename F >
02138 inline
02139 F norm( F a )
02140 {
02141     return a*a ;
02142 }
02143 
02144 template< typename F >
02145 inline
02146 F conj( F a )
02147 {
02148     return a ;
02149 }
02150 
02151 template< typename F >
02152 inline
02153 F inv( F a )
02154 {
02155     return F(1)/a ;
02156 }
02157 
02158 template< typename F >
02159 inline
02160 F dot( F a, F b )
02161 {
02162     return a*b ;
02163 }
02164 
02165 template< typename F >
02166 inline
02167 F cross( F a, F b )
02168 {
02169     return F() ;
02170 }
02171 
02172 } // namespace scalar_func
02173 
02174 } // namespace quat_namespace
02175 
02176 using quat_namespace::quat ;
02177 using quat_namespace::pure ;
02178 
02179 }} // namespace esve::math
02180 
02181 #endif
02182 

Generated on Tue May 30 11:40:53 2006 for esve by doxygen 1.3.4