PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/ilmbase-1.0.2/ImathVec.h
00001 
00002 //
00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
00004 // Digital Ltd. LLC
00005 // 
00006 // All rights reserved.
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are
00010 // met:
00011 // *       Redistributions of source code must retain the above copyright
00012 // notice, this list of conditions and the following disclaimer.
00013 // *       Redistributions in binary form must reproduce the above
00014 // copyright notice, this list of conditions and the following disclaimer
00015 // in the documentation and/or other materials provided with the
00016 // distribution.
00017 // *       Neither the name of Industrial Light & Magic nor the names of
00018 // its contributors may be used to endorse or promote products derived
00019 // from this software without specific prior written permission. 
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //
00034 
00035 
00036 
00037 #ifndef INCLUDED_IMATHVEC_H
00038 #define INCLUDED_IMATHVEC_H
00039 
00040 //----------------------------------------------------
00041 //
00042 //      2D, 3D and 4D point/vector class templates
00043 //
00044 //----------------------------------------------------
00045 
00046 #include "ImathExc.h"
00047 #include "ImathLimits.h"
00048 #include "ImathMath.h"
00049 
00050 #include <iostream>
00051 
00052 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
00053 // suppress exception specification warnings
00054 #pragma warning(push)
00055 #pragma warning(disable:4290)
00056 #endif
00057 
00058 
00059 namespace Imath {
00060 
00061 template <class T> class Vec2;
00062 template <class T> class Vec3;
00063 template <class T> class Vec4;
00064 
00065 enum InfException {INF_EXCEPTION};
00066 
00067 
00068 template <class T> class Vec2
00069 {
00070   public:
00071 
00072     //-------------------
00073     // Access to elements
00074     //-------------------
00075 
00076     T                   x, y;
00077 
00078     T &                 operator [] (int i);
00079     const T &           operator [] (int i) const;
00080 
00081 
00082     //-------------
00083     // Constructors
00084     //-------------
00085 
00086     Vec2 ();                        // no initialization
00087     explicit Vec2 (T a);            // (a a)
00088     Vec2 (T a, T b);                // (a b)
00089 
00090 
00091     //---------------------------------
00092     // Copy constructors and assignment
00093     //---------------------------------
00094 
00095     Vec2 (const Vec2 &v);
00096     template <class S> Vec2 (const Vec2<S> &v);
00097 
00098     const Vec2 &        operator = (const Vec2 &v);
00099 
00100 
00101     //----------------------
00102     // Compatibility with Sb
00103     //----------------------
00104 
00105     template <class S>
00106     void                setValue (S a, S b);
00107 
00108     template <class S>
00109     void                setValue (const Vec2<S> &v);
00110 
00111     template <class S>
00112     void                getValue (S &a, S &b) const;
00113 
00114     template <class S>
00115     void                getValue (Vec2<S> &v) const;
00116 
00117     T *                 getValue ();
00118     const T *           getValue () const;
00119 
00120     
00121     //---------
00122     // Equality
00123     //---------
00124 
00125     template <class S>
00126     bool                operator == (const Vec2<S> &v) const;
00127 
00128     template <class S>
00129     bool                operator != (const Vec2<S> &v) const;
00130 
00131 
00132     //-----------------------------------------------------------------------
00133     // Compare two vectors and test if they are "approximately equal":
00134     //
00135     // equalWithAbsError (v, e)
00136     //
00137     //      Returns true if the coefficients of this and v are the same with
00138     //      an absolute error of no more than e, i.e., for all i
00139     //
00140     //      abs (this[i] - v[i]) <= e
00141     //
00142     // equalWithRelError (v, e)
00143     //
00144     //      Returns true if the coefficients of this and v are the same with
00145     //      a relative error of no more than e, i.e., for all i
00146     //
00147     //      abs (this[i] - v[i]) <= e * abs (this[i])
00148     //-----------------------------------------------------------------------
00149 
00150     bool                equalWithAbsError (const Vec2<T> &v, T e) const;
00151     bool                equalWithRelError (const Vec2<T> &v, T e) const;
00152 
00153     //------------
00154     // Dot product
00155     //------------
00156 
00157     T                   dot (const Vec2 &v) const;
00158     T                   operator ^ (const Vec2 &v) const;
00159 
00160 
00161     //------------------------------------------------
00162     // Right-handed cross product, i.e. z component of
00163     // Vec3 (this->x, this->y, 0) % Vec3 (v.x, v.y, 0)
00164     //------------------------------------------------
00165 
00166     T                   cross (const Vec2 &v) const;
00167     T                   operator % (const Vec2 &v) const;
00168 
00169 
00170     //------------------------
00171     // Component-wise addition
00172     //------------------------
00173 
00174     const Vec2 &        operator += (const Vec2 &v);
00175     Vec2                operator + (const Vec2 &v) const;
00176 
00177 
00178     //---------------------------
00179     // Component-wise subtraction
00180     //---------------------------
00181 
00182     const Vec2 &        operator -= (const Vec2 &v);
00183     Vec2                operator - (const Vec2 &v) const;
00184 
00185 
00186     //------------------------------------
00187     // Component-wise multiplication by -1
00188     //------------------------------------
00189 
00190     Vec2                operator - () const;
00191     const Vec2 &        negate ();
00192 
00193 
00194     //------------------------------
00195     // Component-wise multiplication
00196     //------------------------------
00197 
00198     const Vec2 &        operator *= (const Vec2 &v);
00199     const Vec2 &        operator *= (T a);
00200     Vec2                operator * (const Vec2 &v) const;
00201     Vec2                operator * (T a) const;
00202 
00203 
00204     //------------------------
00205     // Component-wise division
00206     //------------------------
00207 
00208     const Vec2 &        operator /= (const Vec2 &v);
00209     const Vec2 &        operator /= (T a);
00210     Vec2                operator / (const Vec2 &v) const;
00211     Vec2                operator / (T a) const;
00212 
00213 
00214     //----------------------------------------------------------------
00215     // Length and normalization:  If v.length() is 0.0, v.normalize()
00216     // and v.normalized() produce a null vector; v.normalizeExc() and
00217     // v.normalizedExc() throw a NullVecExc.
00218     // v.normalizeNonNull() and v.normalizedNonNull() are slightly
00219     // faster than the other normalization routines, but if v.length()
00220     // is 0.0, the result is undefined.
00221     //----------------------------------------------------------------
00222 
00223     T                   length () const;
00224     T                   length2 () const;
00225 
00226     const Vec2 &        normalize ();           // modifies *this
00227     const Vec2 &        normalizeExc () throw (Iex::MathExc);
00228     const Vec2 &        normalizeNonNull ();
00229 
00230     Vec2<T>             normalized () const;    // does not modify *this
00231     Vec2<T>             normalizedExc () const throw (Iex::MathExc);
00232     Vec2<T>             normalizedNonNull () const;
00233 
00234 
00235     //--------------------------------------------------------
00236     // Number of dimensions, i.e. number of elements in a Vec2
00237     //--------------------------------------------------------
00238 
00239     static unsigned int dimensions() {return 2;}
00240 
00241 
00242     //-------------------------------------------------
00243     // Limitations of type T (see also class limits<T>)
00244     //-------------------------------------------------
00245 
00246     static T            baseTypeMin()           {return limits<T>::min();}
00247     static T            baseTypeMax()           {return limits<T>::max();}
00248     static T            baseTypeSmallest()      {return limits<T>::smallest();}
00249     static T            baseTypeEpsilon()       {return limits<T>::epsilon();}
00250 
00251 
00252     //--------------------------------------------------------------
00253     // Base type -- in templates, which accept a parameter, V, which
00254     // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 
00255     // refer to T as V::BaseType
00256     //--------------------------------------------------------------
00257 
00258     typedef T           BaseType;
00259 
00260   private:
00261 
00262     T                   lengthTiny () const;
00263 };
00264 
00265 
00266 template <class T> class Vec3
00267 {
00268   public:
00269 
00270     //-------------------
00271     // Access to elements
00272     //-------------------
00273 
00274     T                   x, y, z;
00275 
00276     T &                 operator [] (int i);
00277     const T &           operator [] (int i) const;
00278 
00279 
00280     //-------------
00281     // Constructors
00282     //-------------
00283 
00284     Vec3 ();                       // no initialization
00285     explicit Vec3 (T a);           // (a a a)
00286     Vec3 (T a, T b, T c);          // (a b c)
00287 
00288 
00289     //---------------------------------
00290     // Copy constructors and assignment
00291     //---------------------------------
00292 
00293     Vec3 (const Vec3 &v);
00294     template <class S> Vec3 (const Vec3<S> &v);
00295 
00296     const Vec3 &        operator = (const Vec3 &v);
00297 
00298 
00299     //---------------------------------------------------------
00300     // Vec4 to Vec3 conversion, divides x, y and z by w:
00301     //
00302     // The one-argument conversion function divides by w even
00303     // if w is zero.  The result depends on how the environment
00304     // handles floating-point exceptions.
00305     //
00306     // The two-argument version thows an InfPointExc exception
00307     // if w is zero or if division by w would overflow.
00308     //---------------------------------------------------------
00309 
00310     template <class S> explicit Vec3 (const Vec4<S> &v);
00311     template <class S> explicit Vec3 (const Vec4<S> &v, InfException);
00312 
00313 
00314     //----------------------
00315     // Compatibility with Sb
00316     //----------------------
00317 
00318     template <class S>
00319     void                setValue (S a, S b, S c);
00320 
00321     template <class S>
00322     void                setValue (const Vec3<S> &v);
00323 
00324     template <class S>
00325     void                getValue (S &a, S &b, S &c) const;
00326 
00327     template <class S>
00328     void                getValue (Vec3<S> &v) const;
00329 
00330     T *                 getValue();
00331     const T *           getValue() const;
00332 
00333 
00334     //---------
00335     // Equality
00336     //---------
00337 
00338     template <class S>
00339     bool                operator == (const Vec3<S> &v) const;
00340 
00341     template <class S>
00342     bool                operator != (const Vec3<S> &v) const;
00343 
00344     //-----------------------------------------------------------------------
00345     // Compare two vectors and test if they are "approximately equal":
00346     //
00347     // equalWithAbsError (v, e)
00348     //
00349     //      Returns true if the coefficients of this and v are the same with
00350     //      an absolute error of no more than e, i.e., for all i
00351     //
00352     //      abs (this[i] - v[i]) <= e
00353     //
00354     // equalWithRelError (v, e)
00355     //
00356     //      Returns true if the coefficients of this and v are the same with
00357     //      a relative error of no more than e, i.e., for all i
00358     //
00359     //      abs (this[i] - v[i]) <= e * abs (this[i])
00360     //-----------------------------------------------------------------------
00361 
00362     bool                equalWithAbsError (const Vec3<T> &v, T e) const;
00363     bool                equalWithRelError (const Vec3<T> &v, T e) const;
00364 
00365     //------------
00366     // Dot product
00367     //------------
00368 
00369     T                   dot (const Vec3 &v) const;
00370     T                   operator ^ (const Vec3 &v) const;
00371 
00372 
00373     //---------------------------
00374     // Right-handed cross product
00375     //---------------------------
00376 
00377     Vec3                cross (const Vec3 &v) const;
00378     const Vec3 &        operator %= (const Vec3 &v);
00379     Vec3                operator % (const Vec3 &v) const;
00380 
00381 
00382     //------------------------
00383     // Component-wise addition
00384     //------------------------
00385 
00386     const Vec3 &        operator += (const Vec3 &v);
00387     Vec3                operator + (const Vec3 &v) const;
00388 
00389 
00390     //---------------------------
00391     // Component-wise subtraction
00392     //---------------------------
00393 
00394     const Vec3 &        operator -= (const Vec3 &v);
00395     Vec3                operator - (const Vec3 &v) const;
00396 
00397 
00398     //------------------------------------
00399     // Component-wise multiplication by -1
00400     //------------------------------------
00401 
00402     Vec3                operator - () const;
00403     const Vec3 &        negate ();
00404 
00405 
00406     //------------------------------
00407     // Component-wise multiplication
00408     //------------------------------
00409 
00410     const Vec3 &        operator *= (const Vec3 &v);
00411     const Vec3 &        operator *= (T a);
00412     Vec3                operator * (const Vec3 &v) const;
00413     Vec3                operator * (T a) const;
00414 
00415 
00416     //------------------------
00417     // Component-wise division
00418     //------------------------
00419 
00420     const Vec3 &        operator /= (const Vec3 &v);
00421     const Vec3 &        operator /= (T a);
00422     Vec3                operator / (const Vec3 &v) const;
00423     Vec3                operator / (T a) const;
00424 
00425 
00426     //----------------------------------------------------------------
00427     // Length and normalization:  If v.length() is 0.0, v.normalize()
00428     // and v.normalized() produce a null vector; v.normalizeExc() and
00429     // v.normalizedExc() throw a NullVecExc.
00430     // v.normalizeNonNull() and v.normalizedNonNull() are slightly
00431     // faster than the other normalization routines, but if v.length()
00432     // is 0.0, the result is undefined.
00433     //----------------------------------------------------------------
00434 
00435     T                   length () const;
00436     T                   length2 () const;
00437 
00438     const Vec3 &        normalize ();           // modifies *this
00439     const Vec3 &        normalizeExc () throw (Iex::MathExc);
00440     const Vec3 &        normalizeNonNull ();
00441 
00442     Vec3<T>             normalized () const;    // does not modify *this
00443     Vec3<T>             normalizedExc () const throw (Iex::MathExc);
00444     Vec3<T>             normalizedNonNull () const;
00445 
00446 
00447     //--------------------------------------------------------
00448     // Number of dimensions, i.e. number of elements in a Vec3
00449     //--------------------------------------------------------
00450 
00451     static unsigned int dimensions() {return 3;}
00452 
00453 
00454     //-------------------------------------------------
00455     // Limitations of type T (see also class limits<T>)
00456     //-------------------------------------------------
00457 
00458     static T            baseTypeMin()           {return limits<T>::min();}
00459     static T            baseTypeMax()           {return limits<T>::max();}
00460     static T            baseTypeSmallest()      {return limits<T>::smallest();}
00461     static T            baseTypeEpsilon()       {return limits<T>::epsilon();}
00462 
00463 
00464     //--------------------------------------------------------------
00465     // Base type -- in templates, which accept a parameter, V, which
00466     // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 
00467     // refer to T as V::BaseType
00468     //--------------------------------------------------------------
00469 
00470     typedef T           BaseType;
00471 
00472   private:
00473 
00474     T                   lengthTiny () const;
00475 };
00476 
00477 
00478 
00479 template <class T> class Vec4
00480 {
00481   public:
00482 
00483     //-------------------
00484     // Access to elements
00485     //-------------------
00486 
00487     T               x, y, z, w; 
00488 
00489     T &             operator [] (int i);
00490     const T &       operator [] (int i) const;
00491 
00492 
00493     //-------------
00494     // Constructors
00495     //-------------
00496 
00497     Vec4 ();                       // no initialization
00498     explicit Vec4 (T a);           // (a a a a)
00499     Vec4 (T a, T b, T c, T d);     // (a b c d)
00500 
00501 
00502     //---------------------------------
00503     // Copy constructors and assignment
00504     //---------------------------------
00505 
00506     Vec4 (const Vec4 &v);
00507     template <class S> Vec4 (const Vec4<S> &v);
00508 
00509     const Vec4 &    operator = (const Vec4 &v);
00510 
00511 
00512     //-------------------------------------
00513     // Vec3 to Vec4 conversion, sets w to 1
00514     //-------------------------------------
00515 
00516     template <class S> explicit Vec4 (const Vec3<S> &v);
00517 
00518 
00519     //---------
00520     // Equality
00521     //---------
00522 
00523     template <class S>
00524     bool            operator == (const Vec4<S> &v) const;
00525 
00526     template <class S>
00527     bool            operator != (const Vec4<S> &v) const;
00528 
00529 
00530     //-----------------------------------------------------------------------
00531     // Compare two vectors and test if they are "approximately equal":
00532     //
00533     // equalWithAbsError (v, e)
00534     //
00535     //      Returns true if the coefficients of this and v are the same with
00536     //      an absolute error of no more than e, i.e., for all i
00537     //
00538     //      abs (this[i] - v[i]) <= e
00539     //
00540     // equalWithRelError (v, e)
00541     //
00542     //      Returns true if the coefficients of this and v are the same with
00543     //      a relative error of no more than e, i.e., for all i
00544     //
00545     //      abs (this[i] - v[i]) <= e * abs (this[i])
00546     //-----------------------------------------------------------------------
00547 
00548     bool                equalWithAbsError (const Vec4<T> &v, T e) const;
00549     bool                equalWithRelError (const Vec4<T> &v, T e) const;
00550 
00551 
00552     //------------
00553     // Dot product
00554     //------------
00555 
00556     T                   dot (const Vec4 &v) const;
00557     T                   operator ^ (const Vec4 &v) const;
00558 
00559 
00560     //-----------------------------------
00561     // Cross product is not defined in 4D
00562     //-----------------------------------
00563 
00564     //------------------------
00565     // Component-wise addition
00566     //------------------------
00567 
00568     const Vec4 &    operator += (const Vec4 &v);
00569     Vec4            operator + (const Vec4 &v) const;
00570 
00571 
00572     //---------------------------
00573     // Component-wise subtraction
00574     //---------------------------
00575 
00576     const Vec4 &    operator -= (const Vec4 &v);
00577     Vec4            operator - (const Vec4 &v) const;
00578 
00579 
00580     //------------------------------------
00581     // Component-wise multiplication by -1
00582     //------------------------------------
00583 
00584     Vec4            operator - () const;
00585     const Vec4 &    negate ();
00586 
00587 
00588     //------------------------------
00589     // Component-wise multiplication
00590     //------------------------------
00591 
00592     const Vec4 &    operator *= (const Vec4 &v);
00593     const Vec4 &    operator *= (T a);
00594     Vec4            operator * (const Vec4 &v) const;
00595     Vec4            operator * (T a) const;
00596 
00597 
00598     //------------------------
00599     // Component-wise division
00600     //------------------------
00601 
00602     const Vec4 &    operator /= (const Vec4 &v);
00603     const Vec4 &    operator /= (T a);
00604     Vec4            operator / (const Vec4 &v) const;
00605     Vec4            operator / (T a) const;
00606 
00607 
00608     //----------------------------------------------------------------
00609     // Length and normalization:  If v.length() is 0.0, v.normalize()
00610     // and v.normalized() produce a null vector; v.normalizeExc() and
00611     // v.normalizedExc() throw a NullVecExc.
00612     // v.normalizeNonNull() and v.normalizedNonNull() are slightly
00613     // faster than the other normalization routines, but if v.length()
00614     // is 0.0, the result is undefined.
00615     //----------------------------------------------------------------
00616 
00617     T               length () const;
00618     T               length2 () const;
00619 
00620     const Vec4 &    normalize ();           // modifies *this
00621     const Vec4 &    normalizeExc () throw (Iex::MathExc);
00622     const Vec4 &    normalizeNonNull ();
00623 
00624     Vec4<T>         normalized () const;        // does not modify *this
00625     Vec4<T>         normalizedExc () const throw (Iex::MathExc);
00626     Vec4<T>         normalizedNonNull () const;
00627 
00628 
00629     //--------------------------------------------------------
00630     // Number of dimensions, i.e. number of elements in a Vec4
00631     //--------------------------------------------------------
00632 
00633     static unsigned int dimensions() {return 4;}
00634 
00635 
00636     //-------------------------------------------------
00637     // Limitations of type T (see also class limits<T>)
00638     //-------------------------------------------------
00639 
00640     static T            baseTypeMin()           {return limits<T>::min();}
00641     static T            baseTypeMax()           {return limits<T>::max();}
00642     static T            baseTypeSmallest()      {return limits<T>::smallest();}
00643     static T            baseTypeEpsilon()       {return limits<T>::epsilon();}
00644 
00645 
00646     //--------------------------------------------------------------
00647     // Base type -- in templates, which accept a parameter, V, which
00648     // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 
00649     // refer to T as V::BaseType
00650     //--------------------------------------------------------------
00651 
00652     typedef T           BaseType;
00653 
00654   private:
00655 
00656     T                   lengthTiny () const;
00657 };
00658 
00659 
00660 //--------------
00661 // Stream output
00662 //--------------
00663 
00664 template <class T>
00665 std::ostream &  operator << (std::ostream &s, const Vec2<T> &v);
00666 
00667 template <class T>
00668 std::ostream &  operator << (std::ostream &s, const Vec3<T> &v);
00669 
00670 template <class T>
00671 std::ostream &  operator << (std::ostream &s, const Vec4<T> &v);
00672 
00673 //----------------------------------------------------
00674 // Reverse multiplication: S * Vec2<T> and S * Vec3<T>
00675 //----------------------------------------------------
00676 
00677 template <class T> Vec2<T>      operator * (T a, const Vec2<T> &v);
00678 template <class T> Vec3<T>      operator * (T a, const Vec3<T> &v);
00679 template <class T> Vec4<T>      operator * (T a, const Vec4<T> &v);
00680 
00681 
00682 //-------------------------
00683 // Typedefs for convenience
00684 //-------------------------
00685 
00686 typedef Vec2 <short>  V2s;
00687 typedef Vec2 <int>    V2i;
00688 typedef Vec2 <float>  V2f;
00689 typedef Vec2 <double> V2d;
00690 typedef Vec3 <short>  V3s;
00691 typedef Vec3 <int>    V3i;
00692 typedef Vec3 <float>  V3f;
00693 typedef Vec3 <double> V3d;
00694 typedef Vec4 <short>  V4s;
00695 typedef Vec4 <int>    V4i;
00696 typedef Vec4 <float>  V4f;
00697 typedef Vec4 <double> V4d;
00698 
00699 
00700 //-------------------------------------------
00701 // Specializations for VecN<short>, VecN<int>
00702 //-------------------------------------------
00703 
00704 // Vec2<short>
00705 
00706 template <> short
00707 Vec2<short>::length () const;
00708 
00709 template <> const Vec2<short> &
00710 Vec2<short>::normalize ();
00711 
00712 template <> const Vec2<short> &
00713 Vec2<short>::normalizeExc () throw (Iex::MathExc);
00714 
00715 template <> const Vec2<short> &
00716 Vec2<short>::normalizeNonNull ();
00717 
00718 template <> Vec2<short>
00719 Vec2<short>::normalized () const;
00720 
00721 template <> Vec2<short>
00722 Vec2<short>::normalizedExc () const throw (Iex::MathExc);
00723 
00724 template <> Vec2<short>
00725 Vec2<short>::normalizedNonNull () const;
00726 
00727 
00728 // Vec2<int>
00729 
00730 template <> int
00731 Vec2<int>::length () const;
00732 
00733 template <> const Vec2<int> &
00734 Vec2<int>::normalize ();
00735 
00736 template <> const Vec2<int> &
00737 Vec2<int>::normalizeExc () throw (Iex::MathExc);
00738 
00739 template <> const Vec2<int> &
00740 Vec2<int>::normalizeNonNull ();
00741 
00742 template <> Vec2<int>
00743 Vec2<int>::normalized () const;
00744 
00745 template <> Vec2<int>
00746 Vec2<int>::normalizedExc () const throw (Iex::MathExc);
00747 
00748 template <> Vec2<int>
00749 Vec2<int>::normalizedNonNull () const;
00750 
00751 
00752 // Vec3<short>
00753 
00754 template <> short
00755 Vec3<short>::length () const;
00756 
00757 template <> const Vec3<short> &
00758 Vec3<short>::normalize ();
00759 
00760 template <> const Vec3<short> &
00761 Vec3<short>::normalizeExc () throw (Iex::MathExc);
00762 
00763 template <> const Vec3<short> &
00764 Vec3<short>::normalizeNonNull ();
00765 
00766 template <> Vec3<short>
00767 Vec3<short>::normalized () const;
00768 
00769 template <> Vec3<short>
00770 Vec3<short>::normalizedExc () const throw (Iex::MathExc);
00771 
00772 template <> Vec3<short>
00773 Vec3<short>::normalizedNonNull () const;
00774 
00775 
00776 // Vec3<int>
00777 
00778 template <> int
00779 Vec3<int>::length () const;
00780 
00781 template <> const Vec3<int> &
00782 Vec3<int>::normalize ();
00783 
00784 template <> const Vec3<int> &
00785 Vec3<int>::normalizeExc () throw (Iex::MathExc);
00786 
00787 template <> const Vec3<int> &
00788 Vec3<int>::normalizeNonNull ();
00789 
00790 template <> Vec3<int>
00791 Vec3<int>::normalized () const;
00792 
00793 template <> Vec3<int>
00794 Vec3<int>::normalizedExc () const throw (Iex::MathExc);
00795 
00796 template <> Vec3<int>
00797 Vec3<int>::normalizedNonNull () const;
00798 
00799 // Vec4<short>
00800 
00801 template <> short
00802 Vec4<short>::length () const;
00803 
00804 template <> const Vec4<short> &
00805 Vec4<short>::normalize ();
00806 
00807 template <> const Vec4<short> &
00808 Vec4<short>::normalizeExc () throw (Iex::MathExc);
00809 
00810 template <> const Vec4<short> &
00811 Vec4<short>::normalizeNonNull ();
00812 
00813 template <> Vec4<short>
00814 Vec4<short>::normalized () const;
00815 
00816 template <> Vec4<short>
00817 Vec4<short>::normalizedExc () const throw (Iex::MathExc);
00818 
00819 template <> Vec4<short>
00820 Vec4<short>::normalizedNonNull () const;
00821 
00822 
00823 // Vec4<int>
00824 
00825 template <> int
00826 Vec4<int>::length () const;
00827 
00828 template <> const Vec4<int> &
00829 Vec4<int>::normalize ();
00830 
00831 template <> const Vec4<int> &
00832 Vec4<int>::normalizeExc () throw (Iex::MathExc);
00833 
00834 template <> const Vec4<int> &
00835 Vec4<int>::normalizeNonNull ();
00836 
00837 template <> Vec4<int>
00838 Vec4<int>::normalized () const;
00839 
00840 template <> Vec4<int>
00841 Vec4<int>::normalizedExc () const throw (Iex::MathExc);
00842 
00843 template <> Vec4<int>
00844 Vec4<int>::normalizedNonNull () const;
00845 
00846 
00847 //------------------------
00848 // Implementation of Vec2:
00849 //------------------------
00850 
00851 template <class T>
00852 inline T &
00853 Vec2<T>::operator [] (int i)
00854 {
00855     return (&x)[i];
00856 }
00857 
00858 template <class T>
00859 inline const T &
00860 Vec2<T>::operator [] (int i) const
00861 {
00862     return (&x)[i];
00863 }
00864 
00865 template <class T>
00866 inline
00867 Vec2<T>::Vec2 ()
00868 {
00869     // empty
00870 }
00871 
00872 template <class T>
00873 inline
00874 Vec2<T>::Vec2 (T a)
00875 {
00876     x = y = a;
00877 }
00878 
00879 template <class T>
00880 inline
00881 Vec2<T>::Vec2 (T a, T b)
00882 {
00883     x = a;
00884     y = b;
00885 }
00886 
00887 template <class T>
00888 inline
00889 Vec2<T>::Vec2 (const Vec2 &v)
00890 {
00891     x = v.x;
00892     y = v.y;
00893 }
00894 
00895 template <class T>
00896 template <class S>
00897 inline
00898 Vec2<T>::Vec2 (const Vec2<S> &v)
00899 {
00900     x = T (v.x);
00901     y = T (v.y);
00902 }
00903 
00904 template <class T>
00905 inline const Vec2<T> &
00906 Vec2<T>::operator = (const Vec2 &v)
00907 {
00908     x = v.x;
00909     y = v.y;
00910     return *this;
00911 }
00912 
00913 template <class T>
00914 template <class S>
00915 inline void
00916 Vec2<T>::setValue (S a, S b)
00917 {
00918     x = T (a);
00919     y = T (b);
00920 }
00921 
00922 template <class T>
00923 template <class S>
00924 inline void
00925 Vec2<T>::setValue (const Vec2<S> &v)
00926 {
00927     x = T (v.x);
00928     y = T (v.y);
00929 }
00930 
00931 template <class T>
00932 template <class S>
00933 inline void
00934 Vec2<T>::getValue (S &a, S &b) const
00935 {
00936     a = S (x);
00937     b = S (y);
00938 }
00939 
00940 template <class T>
00941 template <class S>
00942 inline void
00943 Vec2<T>::getValue (Vec2<S> &v) const
00944 {
00945     v.x = S (x);
00946     v.y = S (y);
00947 }
00948 
00949 template <class T>
00950 inline T *
00951 Vec2<T>::getValue()
00952 {
00953     return (T *) &x;
00954 }
00955 
00956 template <class T>
00957 inline const T *
00958 Vec2<T>::getValue() const
00959 {
00960     return (const T *) &x;
00961 }
00962 
00963 template <class T>
00964 template <class S>
00965 inline bool
00966 Vec2<T>::operator == (const Vec2<S> &v) const
00967 {
00968     return x == v.x && y == v.y;
00969 }
00970 
00971 template <class T>
00972 template <class S>
00973 inline bool
00974 Vec2<T>::operator != (const Vec2<S> &v) const
00975 {
00976     return x != v.x || y != v.y;
00977 }
00978 
00979 template <class T>
00980 bool
00981 Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
00982 {
00983     for (int i = 0; i < 2; i++)
00984         if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
00985             return false;
00986 
00987     return true;
00988 }
00989 
00990 template <class T>
00991 bool
00992 Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
00993 {
00994     for (int i = 0; i < 2; i++)
00995         if (!Imath::equalWithRelError ((*this)[i], v[i], e))
00996             return false;
00997 
00998     return true;
00999 }
01000 
01001 template <class T>
01002 inline T
01003 Vec2<T>::dot (const Vec2 &v) const
01004 {
01005     return x * v.x + y * v.y;
01006 }
01007 
01008 template <class T>
01009 inline T
01010 Vec2<T>::operator ^ (const Vec2 &v) const
01011 {
01012     return dot (v);
01013 }
01014 
01015 template <class T>
01016 inline T
01017 Vec2<T>::cross (const Vec2 &v) const
01018 {
01019     return x * v.y - y * v.x;
01020 
01021 }
01022 
01023 template <class T>
01024 inline T
01025 Vec2<T>::operator % (const Vec2 &v) const
01026 {
01027     return x * v.y - y * v.x;
01028 }
01029 
01030 template <class T>
01031 inline const Vec2<T> &
01032 Vec2<T>::operator += (const Vec2 &v)
01033 {
01034     x += v.x;
01035     y += v.y;
01036     return *this;
01037 }
01038 
01039 template <class T>
01040 inline Vec2<T>
01041 Vec2<T>::operator + (const Vec2 &v) const
01042 {
01043     return Vec2 (x + v.x, y + v.y);
01044 }
01045 
01046 template <class T>
01047 inline const Vec2<T> &
01048 Vec2<T>::operator -= (const Vec2 &v)
01049 {
01050     x -= v.x;
01051     y -= v.y;
01052     return *this;
01053 }
01054 
01055 template <class T>
01056 inline Vec2<T>
01057 Vec2<T>::operator - (const Vec2 &v) const
01058 {
01059     return Vec2 (x - v.x, y - v.y);
01060 }
01061 
01062 template <class T>
01063 inline Vec2<T>
01064 Vec2<T>::operator - () const
01065 {
01066     return Vec2 (-x, -y);
01067 }
01068 
01069 template <class T>
01070 inline const Vec2<T> &
01071 Vec2<T>::negate ()
01072 {
01073     x = -x;
01074     y = -y;
01075     return *this;
01076 }
01077 
01078 template <class T>
01079 inline const Vec2<T> &
01080 Vec2<T>::operator *= (const Vec2 &v)
01081 {
01082     x *= v.x;
01083     y *= v.y;
01084     return *this;
01085 }
01086 
01087 template <class T>
01088 inline const Vec2<T> &
01089 Vec2<T>::operator *= (T a)
01090 {
01091     x *= a;
01092     y *= a;
01093     return *this;
01094 }
01095 
01096 template <class T>
01097 inline Vec2<T>
01098 Vec2<T>::operator * (const Vec2 &v) const
01099 {
01100     return Vec2 (x * v.x, y * v.y);
01101 }
01102 
01103 template <class T>
01104 inline Vec2<T>
01105 Vec2<T>::operator * (T a) const
01106 {
01107     return Vec2 (x * a, y * a);
01108 }
01109 
01110 template <class T>
01111 inline const Vec2<T> &
01112 Vec2<T>::operator /= (const Vec2 &v)
01113 {
01114     x /= v.x;
01115     y /= v.y;
01116     return *this;
01117 }
01118 
01119 template <class T>
01120 inline const Vec2<T> &
01121 Vec2<T>::operator /= (T a)
01122 {
01123     x /= a;
01124     y /= a;
01125     return *this;
01126 }
01127 
01128 template <class T>
01129 inline Vec2<T>
01130 Vec2<T>::operator / (const Vec2 &v) const
01131 {
01132     return Vec2 (x / v.x, y / v.y);
01133 }
01134 
01135 template <class T>
01136 inline Vec2<T>
01137 Vec2<T>::operator / (T a) const
01138 {
01139     return Vec2 (x / a, y / a);
01140 }
01141 
01142 template <class T>
01143 T
01144 Vec2<T>::lengthTiny () const
01145 {
01146     T absX = (x >= 0)? x: -x;
01147     T absY = (y >= 0)? y: -y;
01148     
01149     T max = absX;
01150 
01151     if (max < absY)
01152         max = absY;
01153 
01154     if (max == 0)
01155         return 0;
01156 
01157     //
01158     // Do not replace the divisions by max with multiplications by 1/max.
01159     // Computing 1/max can overflow but the divisions below will always
01160     // produce results less than or equal to 1.
01161     //
01162 
01163     absX /= max;
01164     absY /= max;
01165 
01166     return max * Math<T>::sqrt (absX * absX + absY * absY);
01167 }
01168 
01169 template <class T>
01170 inline T
01171 Vec2<T>::length () const
01172 {
01173     T length2 = dot (*this);
01174 
01175     if (length2 < 2 * limits<T>::smallest())
01176         return lengthTiny();
01177 
01178     return Math<T>::sqrt (length2);
01179 }
01180 
01181 template <class T>
01182 inline T
01183 Vec2<T>::length2 () const
01184 {
01185     return dot (*this);
01186 }
01187 
01188 template <class T>
01189 const Vec2<T> &
01190 Vec2<T>::normalize ()
01191 {
01192     T l = length();
01193 
01194     if (l != 0)
01195     {
01196         //
01197         // Do not replace the divisions by l with multiplications by 1/l.
01198         // Computing 1/l can overflow but the divisions below will always
01199         // produce results less than or equal to 1.
01200         //
01201 
01202         x /= l;
01203         y /= l;
01204     }
01205 
01206     return *this;
01207 }
01208 
01209 template <class T>
01210 const Vec2<T> &
01211 Vec2<T>::normalizeExc () throw (Iex::MathExc)
01212 {
01213     T l = length();
01214 
01215     if (l == 0)
01216         throw NullVecExc ("Cannot normalize null vector.");
01217 
01218     x /= l;
01219     y /= l;
01220     return *this;
01221 }
01222 
01223 template <class T>
01224 inline
01225 const Vec2<T> &
01226 Vec2<T>::normalizeNonNull ()
01227 {
01228     T l = length();
01229     x /= l;
01230     y /= l;
01231     return *this;
01232 }
01233 
01234 template <class T>
01235 Vec2<T>
01236 Vec2<T>::normalized () const
01237 {
01238     T l = length();
01239 
01240     if (l == 0)
01241         return Vec2 (T (0));
01242 
01243     return Vec2 (x / l, y / l);
01244 }
01245 
01246 template <class T>
01247 Vec2<T>
01248 Vec2<T>::normalizedExc () const throw (Iex::MathExc)
01249 {
01250     T l = length();
01251 
01252     if (l == 0)
01253         throw NullVecExc ("Cannot normalize null vector.");
01254 
01255     return Vec2 (x / l, y / l);
01256 }
01257 
01258 template <class T>
01259 inline
01260 Vec2<T>
01261 Vec2<T>::normalizedNonNull () const
01262 {
01263     T l = length();
01264     return Vec2 (x / l, y / l);
01265 }
01266 
01267 
01268 //-----------------------
01269 // Implementation of Vec3
01270 //-----------------------
01271 
01272 template <class T>
01273 inline T &
01274 Vec3<T>::operator [] (int i)
01275 {
01276     return (&x)[i];
01277 }
01278 
01279 template <class T>
01280 inline const T &
01281 Vec3<T>::operator [] (int i) const
01282 {
01283     return (&x)[i];
01284 }
01285 
01286 template <class T>
01287 inline
01288 Vec3<T>::Vec3 ()
01289 {
01290     // empty
01291 }
01292 
01293 template <class T>
01294 inline
01295 Vec3<T>::Vec3 (T a)
01296 {
01297     x = y = z = a;
01298 }
01299 
01300 template <class T>
01301 inline
01302 Vec3<T>::Vec3 (T a, T b, T c)
01303 {
01304     x = a;
01305     y = b;
01306     z = c;
01307 }
01308 
01309 template <class T>
01310 inline
01311 Vec3<T>::Vec3 (const Vec3 &v)
01312 {
01313     x = v.x;
01314     y = v.y;
01315     z = v.z;
01316 }
01317 
01318 template <class T>
01319 template <class S>
01320 inline
01321 Vec3<T>::Vec3 (const Vec3<S> &v)
01322 {
01323     x = T (v.x);
01324     y = T (v.y);
01325     z = T (v.z);
01326 }
01327 
01328 template <class T>
01329 inline const Vec3<T> &
01330 Vec3<T>::operator = (const Vec3 &v)
01331 {
01332     x = v.x;
01333     y = v.y;
01334     z = v.z;
01335     return *this;
01336 }
01337 
01338 template <class T>
01339 template <class S>
01340 inline
01341 Vec3<T>::Vec3 (const Vec4<S> &v)
01342 {
01343     x = T (v.x / v.w);
01344     y = T (v.y / v.w);
01345     z = T (v.z / v.w);
01346 }
01347 
01348 template <class T>
01349 template <class S>
01350 Vec3<T>::Vec3 (const Vec4<S> &v, InfException)
01351 {
01352     T vx = T (v.x);
01353     T vy = T (v.y);
01354     T vz = T (v.z);
01355     T vw = T (v.w);
01356 
01357     T absW = (vw >= 0)? vw: -vw;
01358 
01359     if (absW < 1)
01360     {
01361         T m = baseTypeMax() * absW;
01362         
01363         if (vx <= -m || vx >= m || vy <= -m || vy >= m || vz <= -m || vz >= m)
01364             throw InfPointExc ("Cannot normalize point at infinity.");
01365     }
01366 
01367     x = vx / vw;
01368     y = vy / vw;
01369     z = vz / vw;
01370 }
01371 
01372 template <class T>
01373 template <class S>
01374 inline void
01375 Vec3<T>::setValue (S a, S b, S c)
01376 {
01377     x = T (a);
01378     y = T (b);
01379     z = T (c);
01380 }
01381 
01382 template <class T>
01383 template <class S>
01384 inline void
01385 Vec3<T>::setValue (const Vec3<S> &v)
01386 {
01387     x = T (v.x);
01388     y = T (v.y);
01389     z = T (v.z);
01390 }
01391 
01392 template <class T>
01393 template <class S>
01394 inline void
01395 Vec3<T>::getValue (S &a, S &b, S &c) const
01396 {
01397     a = S (x);
01398     b = S (y);
01399     c = S (z);
01400 }
01401 
01402 template <class T>
01403 template <class S>
01404 inline void
01405 Vec3<T>::getValue (Vec3<S> &v) const
01406 {
01407     v.x = S (x);
01408     v.y = S (y);
01409     v.z = S (z);
01410 }
01411 
01412 template <class T>
01413 inline T *
01414 Vec3<T>::getValue()
01415 {
01416     return (T *) &x;
01417 }
01418 
01419 template <class T>
01420 inline const T *
01421 Vec3<T>::getValue() const
01422 {
01423     return (const T *) &x;
01424 }
01425 
01426 template <class T>
01427 template <class S>
01428 inline bool
01429 Vec3<T>::operator == (const Vec3<S> &v) const
01430 {
01431     return x == v.x && y == v.y && z == v.z;
01432 }
01433 
01434 template <class T>
01435 template <class S>
01436 inline bool
01437 Vec3<T>::operator != (const Vec3<S> &v) const
01438 {
01439     return x != v.x || y != v.y || z != v.z;
01440 }
01441 
01442 template <class T>
01443 bool
01444 Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
01445 {
01446     for (int i = 0; i < 3; i++)
01447         if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
01448             return false;
01449 
01450     return true;
01451 }
01452 
01453 template <class T>
01454 bool
01455 Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
01456 {
01457     for (int i = 0; i < 3; i++)
01458         if (!Imath::equalWithRelError ((*this)[i], v[i], e))
01459             return false;
01460 
01461     return true;
01462 }
01463 
01464 template <class T>
01465 inline T
01466 Vec3<T>::dot (const Vec3 &v) const
01467 {
01468     return x * v.x + y * v.y + z * v.z;
01469 }
01470 
01471 template <class T>
01472 inline T
01473 Vec3<T>::operator ^ (const Vec3 &v) const
01474 {
01475     return dot (v);
01476 }
01477 
01478 template <class T>
01479 inline Vec3<T>
01480 Vec3<T>::cross (const Vec3 &v) const
01481 {
01482     return Vec3 (y * v.z - z * v.y,
01483                  z * v.x - x * v.z,
01484                  x * v.y - y * v.x);
01485 }
01486 
01487 template <class T>
01488 inline const Vec3<T> &
01489 Vec3<T>::operator %= (const Vec3 &v)
01490 {
01491     T a = y * v.z - z * v.y;
01492     T b = z * v.x - x * v.z;
01493     T c = x * v.y - y * v.x;
01494     x = a;
01495     y = b;
01496     z = c;
01497     return *this;
01498 }
01499 
01500 template <class T>
01501 inline Vec3<T>
01502 Vec3<T>::operator % (const Vec3 &v) const
01503 {
01504     return Vec3 (y * v.z - z * v.y,
01505                  z * v.x - x * v.z,
01506                  x * v.y - y * v.x);
01507 }
01508 
01509 template <class T>
01510 inline const Vec3<T> &
01511 Vec3<T>::operator += (const Vec3 &v)
01512 {
01513     x += v.x;
01514     y += v.y;
01515     z += v.z;
01516     return *this;
01517 }
01518 
01519 template <class T>
01520 inline Vec3<T>
01521 Vec3<T>::operator + (const Vec3 &v) const
01522 {
01523     return Vec3 (x + v.x, y + v.y, z + v.z);
01524 }
01525 
01526 template <class T>
01527 inline const Vec3<T> &
01528 Vec3<T>::operator -= (const Vec3 &v)
01529 {
01530     x -= v.x;
01531     y -= v.y;
01532     z -= v.z;
01533     return *this;
01534 }
01535 
01536 template <class T>
01537 inline Vec3<T>
01538 Vec3<T>::operator - (const Vec3 &v) const
01539 {
01540     return Vec3 (x - v.x, y - v.y, z - v.z);
01541 }
01542 
01543 template <class T>
01544 inline Vec3<T>
01545 Vec3<T>::operator - () const
01546 {
01547     return Vec3 (-x, -y, -z);
01548 }
01549 
01550 template <class T>
01551 inline const Vec3<T> &
01552 Vec3<T>::negate ()
01553 {
01554     x = -x;
01555     y = -y;
01556     z = -z;
01557     return *this;
01558 }
01559 
01560 template <class T>
01561 inline const Vec3<T> &
01562 Vec3<T>::operator *= (const Vec3 &v)
01563 {
01564     x *= v.x;
01565     y *= v.y;
01566     z *= v.z;
01567     return *this;
01568 }
01569 
01570 template <class T>
01571 inline const Vec3<T> &
01572 Vec3<T>::operator *= (T a)
01573 {
01574     x *= a;
01575     y *= a;
01576     z *= a;
01577     return *this;
01578 }
01579 
01580 template <class T>
01581 inline Vec3<T>
01582 Vec3<T>::operator * (const Vec3 &v) const
01583 {
01584     return Vec3 (x * v.x, y * v.y, z * v.z);
01585 }
01586 
01587 template <class T>
01588 inline Vec3<T>
01589 Vec3<T>::operator * (T a) const
01590 {
01591     return Vec3 (x * a, y * a, z * a);
01592 }
01593 
01594 template <class T>
01595 inline const Vec3<T> &
01596 Vec3<T>::operator /= (const Vec3 &v)
01597 {
01598     x /= v.x;
01599     y /= v.y;
01600     z /= v.z;
01601     return *this;
01602 }
01603 
01604 template <class T>
01605 inline const Vec3<T> &
01606 Vec3<T>::operator /= (T a)
01607 {
01608     x /= a;
01609     y /= a;
01610     z /= a;
01611     return *this;
01612 }
01613 
01614 template <class T>
01615 inline Vec3<T>
01616 Vec3<T>::operator / (const Vec3 &v) const
01617 {
01618     return Vec3 (x / v.x, y / v.y, z / v.z);
01619 }
01620 
01621 template <class T>
01622 inline Vec3<T>
01623 Vec3<T>::operator / (T a) const
01624 {
01625     return Vec3 (x / a, y / a, z / a);
01626 }
01627 
01628 template <class T>
01629 T
01630 Vec3<T>::lengthTiny () const
01631 {
01632     T absX = (x >= 0)? x: -x;
01633     T absY = (y >= 0)? y: -y;
01634     T absZ = (z >= 0)? z: -z;
01635     
01636     T max = absX;
01637 
01638     if (max < absY)
01639         max = absY;
01640 
01641     if (max < absZ)
01642         max = absZ;
01643 
01644     if (max == 0)
01645         return 0;
01646 
01647     //
01648     // Do not replace the divisions by max with multiplications by 1/max.
01649     // Computing 1/max can overflow but the divisions below will always
01650     // produce results less than or equal to 1.
01651     //
01652 
01653     absX /= max;
01654     absY /= max;
01655     absZ /= max;
01656 
01657     return max * Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ);
01658 }
01659 
01660 template <class T>
01661 inline T
01662 Vec3<T>::length () const
01663 {
01664     T length2 = dot (*this);
01665 
01666     if (length2 < 2 * limits<T>::smallest())
01667         return lengthTiny();
01668 
01669     return Math<T>::sqrt (length2);
01670 }
01671 
01672 template <class T>
01673 inline T
01674 Vec3<T>::length2 () const
01675 {
01676     return dot (*this);
01677 }
01678 
01679 template <class T>
01680 const Vec3<T> &
01681 Vec3<T>::normalize ()
01682 {
01683     T l = length();
01684 
01685     if (l != 0)
01686     {
01687         //
01688         // Do not replace the divisions by l with multiplications by 1/l.
01689         // Computing 1/l can overflow but the divisions below will always
01690         // produce results less than or equal to 1.
01691         //
01692 
01693         x /= l;
01694         y /= l;
01695         z /= l;
01696     }
01697 
01698     return *this;
01699 }
01700 
01701 template <class T>
01702 const Vec3<T> &
01703 Vec3<T>::normalizeExc () throw (Iex::MathExc)
01704 {
01705     T l = length();
01706 
01707     if (l == 0)
01708         throw NullVecExc ("Cannot normalize null vector.");
01709 
01710     x /= l;
01711     y /= l;
01712     z /= l;
01713     return *this;
01714 }
01715 
01716 template <class T>
01717 inline
01718 const Vec3<T> &
01719 Vec3<T>::normalizeNonNull ()
01720 {
01721     T l = length();
01722     x /= l;
01723     y /= l;
01724     z /= l;
01725     return *this;
01726 }
01727 
01728 template <class T>
01729 Vec3<T>
01730 Vec3<T>::normalized () const
01731 {
01732     T l = length();
01733 
01734     if (l == 0)
01735         return Vec3 (T (0));
01736 
01737     return Vec3 (x / l, y / l, z / l);
01738 }
01739 
01740 template <class T>
01741 Vec3<T>
01742 Vec3<T>::normalizedExc () const throw (Iex::MathExc)
01743 {
01744     T l = length();
01745 
01746     if (l == 0)
01747         throw NullVecExc ("Cannot normalize null vector.");
01748 
01749     return Vec3 (x / l, y / l, z / l);
01750 }
01751 
01752 template <class T>
01753 inline
01754 Vec3<T>
01755 Vec3<T>::normalizedNonNull () const
01756 {
01757     T l = length();
01758     return Vec3 (x / l, y / l, z / l);
01759 }
01760 
01761 
01762 //-----------------------
01763 // Implementation of Vec4
01764 //-----------------------
01765 
01766 template <class T>
01767 inline T &
01768 Vec4<T>::operator [] (int i)
01769 {
01770     return (&x)[i];
01771 }
01772 
01773 template <class T>
01774 inline const T &
01775 Vec4<T>::operator [] (int i) const
01776 {
01777     return (&x)[i];
01778 }
01779 
01780 template <class T>
01781 inline
01782 Vec4<T>::Vec4 ()
01783 {
01784     // empty
01785 }
01786 
01787 template <class T>
01788 inline
01789 Vec4<T>::Vec4 (T a)
01790 {
01791     x = y = z = w = a;
01792 }
01793 
01794 template <class T>
01795 inline
01796 Vec4<T>::Vec4 (T a, T b, T c, T d)
01797 {
01798     x = a;
01799     y = b;
01800     z = c;
01801     w = d;
01802 }
01803 
01804 template <class T>
01805 inline
01806 Vec4<T>::Vec4 (const Vec4 &v)
01807 {
01808     x = v.x;
01809     y = v.y;
01810     z = v.z;
01811     w = v.w;
01812 }
01813 
01814 template <class T>
01815 template <class S>
01816 inline
01817 Vec4<T>::Vec4 (const Vec4<S> &v)
01818 {
01819     x = T (v.x);
01820     y = T (v.y);
01821     z = T (v.z);
01822     w = T (v.w);
01823 }
01824 
01825 template <class T>
01826 inline const Vec4<T> &
01827 Vec4<T>::operator = (const Vec4 &v)
01828 {
01829     x = v.x;
01830     y = v.y;
01831     z = v.z;
01832     w = v.w;
01833     return *this;
01834 }
01835 
01836 template <class T>
01837 template <class S>
01838 inline
01839 Vec4<T>::Vec4 (const Vec3<S> &v)
01840 {
01841     x = T (v.x);
01842     y = T (v.y);
01843     z = T (v.z);
01844     w = T (1);
01845 }
01846 
01847 template <class T>
01848 template <class S>
01849 inline bool
01850 Vec4<T>::operator == (const Vec4<S> &v) const
01851 {
01852     return x == v.x && y == v.y && z == v.z && w == v.w;
01853 }
01854 
01855 template <class T>
01856 template <class S>
01857 inline bool
01858 Vec4<T>::operator != (const Vec4<S> &v) const
01859 {
01860     return x != v.x || y != v.y || z != v.z || w != v.w;
01861 }
01862 
01863 template <class T>
01864 bool
01865 Vec4<T>::equalWithAbsError (const Vec4<T> &v, T e) const
01866 {
01867     for (int i = 0; i < 4; i++)
01868         if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
01869             return false;
01870 
01871     return true;
01872 }
01873 
01874 template <class T>
01875 bool
01876 Vec4<T>::equalWithRelError (const Vec4<T> &v, T e) const
01877 {
01878     for (int i = 0; i < 4; i++)
01879         if (!Imath::equalWithRelError ((*this)[i], v[i], e))
01880             return false;
01881 
01882     return true;
01883 }
01884 
01885 template <class T>
01886 inline T
01887 Vec4<T>::dot (const Vec4 &v) const
01888 {
01889     return x * v.x + y * v.y + z * v.z + w * v.w;
01890 }
01891 
01892 template <class T>
01893 inline T
01894 Vec4<T>::operator ^ (const Vec4 &v) const
01895 {
01896     return dot (v);
01897 }
01898 
01899 
01900 template <class T>
01901 inline const Vec4<T> &
01902 Vec4<T>::operator += (const Vec4 &v)
01903 {
01904     x += v.x;
01905     y += v.y;
01906     z += v.z;
01907     w += v.w;
01908     return *this;
01909 }
01910 
01911 template <class T>
01912 inline Vec4<T>
01913 Vec4<T>::operator + (const Vec4 &v) const
01914 {
01915     return Vec4 (x + v.x, y + v.y, z + v.z, w + v.w);
01916 }
01917 
01918 template <class T>
01919 inline const Vec4<T> &
01920 Vec4<T>::operator -= (const Vec4 &v)
01921 {
01922     x -= v.x;
01923     y -= v.y;
01924     z -= v.z;
01925     w -= v.w;
01926     return *this;
01927 }
01928 
01929 template <class T>
01930 inline Vec4<T>
01931 Vec4<T>::operator - (const Vec4 &v) const
01932 {
01933     return Vec4 (x - v.x, y - v.y, z - v.z, w - v.w);
01934 }
01935 
01936 template <class T>
01937 inline Vec4<T>
01938 Vec4<T>::operator - () const
01939 {
01940     return Vec4 (-x, -y, -z, -w);
01941 }
01942 
01943 template <class T>
01944 inline const Vec4<T> &
01945 Vec4<T>::negate ()
01946 {
01947     x = -x;
01948     y = -y;
01949     z = -z;
01950     w = -w;
01951     return *this;
01952 }
01953 
01954 template <class T>
01955 inline const Vec4<T> &
01956 Vec4<T>::operator *= (const Vec4 &v)
01957 {
01958     x *= v.x;
01959     y *= v.y;
01960     z *= v.z;
01961     w *= v.w;
01962     return *this;
01963 }
01964 
01965 template <class T>
01966 inline const Vec4<T> &
01967 Vec4<T>::operator *= (T a)
01968 {
01969     x *= a;
01970     y *= a;
01971     z *= a;
01972     w *= a;
01973     return *this;
01974 }
01975 
01976 template <class T>
01977 inline Vec4<T>
01978 Vec4<T>::operator * (const Vec4 &v) const
01979 {
01980     return Vec4 (x * v.x, y * v.y, z * v.z, w * v.w);
01981 }
01982 
01983 template <class T>
01984 inline Vec4<T>
01985 Vec4<T>::operator * (T a) const
01986 {
01987     return Vec4 (x * a, y * a, z * a, w * a);
01988 }
01989 
01990 template <class T>
01991 inline const Vec4<T> &
01992 Vec4<T>::operator /= (const Vec4 &v)
01993 {
01994     x /= v.x;
01995     y /= v.y;
01996     z /= v.z;
01997     w /= v.w;
01998     return *this;
01999 }
02000 
02001 template <class T>
02002 inline const Vec4<T> &
02003 Vec4<T>::operator /= (T a)
02004 {
02005     x /= a;
02006     y /= a;
02007     z /= a;
02008     w /= a;
02009     return *this;
02010 }
02011 
02012 template <class T>
02013 inline Vec4<T>
02014 Vec4<T>::operator / (const Vec4 &v) const
02015 {
02016     return Vec4 (x / v.x, y / v.y, z / v.z, w / v.w);
02017 }
02018 
02019 template <class T>
02020 inline Vec4<T>
02021 Vec4<T>::operator / (T a) const
02022 {
02023     return Vec4 (x / a, y / a, z / a, w / a);
02024 }
02025 
02026 template <class T>
02027 T
02028 Vec4<T>::lengthTiny () const
02029 {
02030     T absX = (x >= 0)? x: -x;
02031     T absY = (y >= 0)? y: -y;
02032     T absZ = (z >= 0)? z: -z;
02033     T absW = (w >= 0)? w: -w;
02034     
02035     T max = absX;
02036 
02037     if (max < absY)
02038         max = absY;
02039 
02040     if (max < absZ)
02041         max = absZ;
02042 
02043     if (max < absW)
02044         max = absW;
02045 
02046     if (max == 0)
02047         return 0;
02048 
02049     //
02050     // Do not replace the divisions by max with multiplications by 1/max.
02051     // Computing 1/max can overflow but the divisions below will always
02052     // produce results less than or equal to 1.
02053     //
02054 
02055     absX /= max;
02056     absY /= max;
02057     absZ /= max;
02058     absW /= max;
02059 
02060     return max *
02061         Math<T>::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW);
02062 }
02063 
02064 template <class T>
02065 inline T
02066 Vec4<T>::length () const
02067 {
02068     T length2 = dot (*this);
02069 
02070     if (length2 < 2 * limits<T>::smallest())
02071         return lengthTiny();
02072 
02073     return Math<T>::sqrt (length2);
02074 }
02075 
02076 template <class T>
02077 inline T
02078 Vec4<T>::length2 () const
02079 {
02080     return dot (*this);
02081 }
02082 
02083 template <class T>
02084 const Vec4<T> &
02085 Vec4<T>::normalize ()
02086 {
02087     T l = length();
02088 
02089     if (l != 0)
02090     {
02091         //
02092         // Do not replace the divisions by l with multiplications by 1/l.
02093         // Computing 1/l can overflow but the divisions below will always
02094         // produce results less than or equal to 1.
02095         //
02096 
02097         x /= l;
02098         y /= l;
02099         z /= l;
02100         w /= l;
02101     }
02102 
02103     return *this;
02104 }
02105 
02106 template <class T>
02107 const Vec4<T> &
02108 Vec4<T>::normalizeExc () throw (Iex::MathExc)
02109 {
02110     T l = length();
02111 
02112     if (l == 0)
02113         throw NullVecExc ("Cannot normalize null vector.");
02114 
02115     x /= l;
02116     y /= l;
02117     z /= l;
02118     w /= l;
02119     return *this;
02120 }
02121 
02122 template <class T>
02123 inline
02124 const Vec4<T> &
02125 Vec4<T>::normalizeNonNull ()
02126 {
02127     T l = length();
02128     x /= l;
02129     y /= l;
02130     z /= l;
02131     w /= l;
02132     return *this;
02133 }
02134 
02135 template <class T>
02136 Vec4<T>
02137 Vec4<T>::normalized () const
02138 {
02139     T l = length();
02140 
02141     if (l == 0)
02142         return Vec4 (T (0));
02143 
02144     return Vec4 (x / l, y / l, z / l, w / l);
02145 }
02146 
02147 template <class T>
02148 Vec4<T>
02149 Vec4<T>::normalizedExc () const throw (Iex::MathExc)
02150 {
02151     T l = length();
02152 
02153     if (l == 0)
02154         throw NullVecExc ("Cannot normalize null vector.");
02155 
02156     return Vec4 (x / l, y / l, z / l, w / l);
02157 }
02158 
02159 template <class T>
02160 inline
02161 Vec4<T>
02162 Vec4<T>::normalizedNonNull () const
02163 {
02164     T l = length();
02165     return Vec4 (x / l, y / l, z / l, w / l);
02166 }
02167 
02168 //-----------------------------
02169 // Stream output implementation
02170 //-----------------------------
02171 
02172 template <class T>
02173 std::ostream &
02174 operator << (std::ostream &s, const Vec2<T> &v)
02175 {
02176     return s << '(' << v.x << ' ' << v.y << ')';
02177 }
02178 
02179 template <class T>
02180 std::ostream &
02181 operator << (std::ostream &s, const Vec3<T> &v)
02182 {
02183     return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
02184 }
02185 
02186 template <class T>
02187 std::ostream &
02188 operator << (std::ostream &s, const Vec4<T> &v)
02189 {
02190     return s << '(' << v.x << ' ' << v.y << ' ' << v.z << ' ' << v.w << ')';
02191 }
02192 
02193 
02194 //-----------------------------------------
02195 // Implementation of reverse multiplication
02196 //-----------------------------------------
02197 
02198 template <class T>
02199 inline Vec2<T>
02200 operator * (T a, const Vec2<T> &v)
02201 {
02202     return Vec2<T> (a * v.x, a * v.y);
02203 }
02204 
02205 template <class T>
02206 inline Vec3<T>
02207 operator * (T a, const Vec3<T> &v)
02208 {
02209     return Vec3<T> (a * v.x, a * v.y, a * v.z);
02210 }
02211 
02212 template <class T>
02213 inline Vec4<T>
02214 operator * (T a, const Vec4<T> &v)
02215 {
02216     return Vec4<T> (a * v.x, a * v.y, a * v.z, a * v.w);
02217 }
02218 
02219 
02220 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
02221 #pragma warning(pop)
02222 #endif
02223 
02224 } // namespace Imath
02225 
02226 #endif