PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/ilmbase-1.0.2/ImathShear.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_IMATHSHEAR_H
00038 #define INCLUDED_IMATHSHEAR_H
00039 
00040 //----------------------------------------------------
00041 //
00042 //      Shear6 class template.
00043 //
00044 //----------------------------------------------------
00045 
00046 #include "ImathExc.h"
00047 #include "ImathLimits.h"
00048 #include "ImathMath.h"
00049 #include "ImathVec.h"
00050 
00051 #include <iostream>
00052 
00053 
00054 namespace Imath {
00055 
00056 
00057 
00058 
00059 template <class T> class Shear6
00060 {
00061   public:
00062 
00063     //-------------------
00064     // Access to elements
00065     //-------------------
00066 
00067     T                   xy, xz, yz, yx, zx, zy;
00068 
00069     T &                 operator [] (int i);
00070     const T &           operator [] (int i) const;
00071 
00072 
00073     //-------------
00074     // Constructors
00075     //-------------
00076 
00077     Shear6 ();                     // (0 0 0 0 0 0)
00078     Shear6 (T XY, T XZ, T YZ);     // (XY XZ YZ 0 0 0)
00079     Shear6 (const Vec3<T> &v);     // (v.x v.y v.z 0 0 0)
00080     template <class S>             // (v.x v.y v.z 0 0 0)
00081         Shear6 (const Vec3<S> &v);
00082     Shear6 (T XY, T XZ, T YZ,      // (XY XZ YZ YX ZX ZY)
00083             T YX, T ZX, T ZY);  
00084 
00085 
00086     //---------------------------------
00087     // Copy constructors and assignment
00088     //---------------------------------
00089 
00090     Shear6 (const Shear6 &h);
00091     template <class S> Shear6 (const Shear6<S> &h);
00092 
00093     const Shear6 &      operator = (const Shear6 &h);
00094     template <class S> 
00095         const Shear6 &  operator = (const Vec3<S> &v);
00096 
00097 
00098     //----------------------
00099     // Compatibility with Sb
00100     //----------------------
00101 
00102     template <class S>
00103     void                setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY);
00104 
00105     template <class S>
00106     void                setValue (const Shear6<S> &h);
00107 
00108     template <class S>
00109     void                getValue (S &XY, S &XZ, S &YZ, 
00110                                   S &YX, S &ZX, S &ZY) const;
00111 
00112     template <class S>
00113     void                getValue (Shear6<S> &h) const;
00114 
00115     T *                 getValue();
00116     const T *           getValue() const;
00117 
00118 
00119     //---------
00120     // Equality
00121     //---------
00122 
00123     template <class S>
00124     bool                operator == (const Shear6<S> &h) const;
00125 
00126     template <class S>
00127     bool                operator != (const Shear6<S> &h) const;
00128 
00129     //-----------------------------------------------------------------------
00130     // Compare two shears and test if they are "approximately equal":
00131     //
00132     // equalWithAbsError (h, e)
00133     //
00134     //      Returns true if the coefficients of this and h are the same with
00135     //      an absolute error of no more than e, i.e., for all i
00136     //
00137     //      abs (this[i] - h[i]) <= e
00138     //
00139     // equalWithRelError (h, e)
00140     //
00141     //      Returns true if the coefficients of this and h are the same with
00142     //      a relative error of no more than e, i.e., for all i
00143     //
00144     //      abs (this[i] - h[i]) <= e * abs (this[i])
00145     //-----------------------------------------------------------------------
00146 
00147     bool                equalWithAbsError (const Shear6<T> &h, T e) const;
00148     bool                equalWithRelError (const Shear6<T> &h, T e) const;
00149 
00150 
00151     //------------------------
00152     // Component-wise addition
00153     //------------------------
00154 
00155     const Shear6 &      operator += (const Shear6 &h);
00156     Shear6              operator + (const Shear6 &h) const;
00157 
00158 
00159     //---------------------------
00160     // Component-wise subtraction
00161     //---------------------------
00162 
00163     const Shear6 &      operator -= (const Shear6 &h);
00164     Shear6              operator - (const Shear6 &h) const;
00165 
00166 
00167     //------------------------------------
00168     // Component-wise multiplication by -1
00169     //------------------------------------
00170 
00171     Shear6              operator - () const;
00172     const Shear6 &      negate ();
00173 
00174 
00175     //------------------------------
00176     // Component-wise multiplication
00177     //------------------------------
00178 
00179     const Shear6 &      operator *= (const Shear6 &h);
00180     const Shear6 &      operator *= (T a);
00181     Shear6              operator * (const Shear6 &h) const;
00182     Shear6              operator * (T a) const;
00183 
00184 
00185     //------------------------
00186     // Component-wise division
00187     //------------------------
00188 
00189     const Shear6 &      operator /= (const Shear6 &h);
00190     const Shear6 &      operator /= (T a);
00191     Shear6              operator / (const Shear6 &h) const;
00192     Shear6              operator / (T a) const;
00193 
00194 
00195     //----------------------------------------------------------
00196     // Number of dimensions, i.e. number of elements in a Shear6
00197     //----------------------------------------------------------
00198 
00199     static unsigned int dimensions() {return 6;}
00200 
00201 
00202     //-------------------------------------------------
00203     // Limitations of type T (see also class limits<T>)
00204     //-------------------------------------------------
00205 
00206     static T            baseTypeMin()           {return limits<T>::min();}
00207     static T            baseTypeMax()           {return limits<T>::max();}
00208     static T            baseTypeSmallest()      {return limits<T>::smallest();}
00209     static T            baseTypeEpsilon()       {return limits<T>::epsilon();}
00210 
00211 
00212     //--------------------------------------------------------------
00213     // Base type -- in templates, which accept a parameter, V, which
00214     // could be either a Vec2<T> or a Shear6<T>, you can refer to T as
00215     // V::BaseType
00216     //--------------------------------------------------------------
00217 
00218     typedef T           BaseType;
00219 };
00220 
00221 
00222 //--------------
00223 // Stream output
00224 //--------------
00225 
00226 template <class T>
00227 std::ostream &  operator << (std::ostream &s, const Shear6<T> &h);
00228 
00229 
00230 //----------------------------------------------------
00231 // Reverse multiplication: scalar * Shear6<T>
00232 //----------------------------------------------------
00233 
00234 template <class S, class T> Shear6<T>   operator * (S a, const Shear6<T> &h);
00235 
00236 
00237 //-------------------------
00238 // Typedefs for convenience
00239 //-------------------------
00240 
00241 typedef Vec3   <float>  Shear3f;
00242 typedef Vec3   <double> Shear3d;
00243 typedef Shear6 <float>  Shear6f;
00244 typedef Shear6 <double> Shear6d;
00245 
00246 
00247 
00248 
00249 //-----------------------
00250 // Implementation of Shear6
00251 //-----------------------
00252 
00253 template <class T>
00254 inline T &
00255 Shear6<T>::operator [] (int i)
00256 {
00257     return (&xy)[i];
00258 }
00259 
00260 template <class T>
00261 inline const T &
00262 Shear6<T>::operator [] (int i) const
00263 {
00264     return (&xy)[i];
00265 }
00266 
00267 template <class T>
00268 inline
00269 Shear6<T>::Shear6 ()
00270 {
00271     xy = xz = yz = yx = zx = zy = 0;
00272 }
00273 
00274 template <class T>
00275 inline
00276 Shear6<T>::Shear6 (T XY, T XZ, T YZ)
00277 {
00278     xy = XY;
00279     xz = XZ;
00280     yz = YZ;
00281     yx = 0;
00282     zx = 0;
00283     zy = 0;
00284 }
00285 
00286 template <class T>
00287 inline
00288 Shear6<T>::Shear6 (const Vec3<T> &v)
00289 {
00290     xy = v.x;
00291     xz = v.y;
00292     yz = v.z;
00293     yx = 0;
00294     zx = 0;
00295     zy = 0;
00296 }
00297 
00298 template <class T>
00299 template <class S>
00300 inline
00301 Shear6<T>::Shear6 (const Vec3<S> &v)
00302 {
00303     xy = T (v.x);
00304     xz = T (v.y);
00305     yz = T (v.z);
00306     yx = 0;
00307     zx = 0;
00308     zy = 0;
00309 }
00310 
00311 template <class T>
00312 inline
00313 Shear6<T>::Shear6 (T XY, T XZ, T YZ, T YX, T ZX, T ZY)
00314 {
00315     xy = XY;
00316     xz = XZ;
00317     yz = YZ;
00318     yx = YX;
00319     zx = ZX;
00320     zy = ZY;
00321 }
00322 
00323 template <class T>
00324 inline
00325 Shear6<T>::Shear6 (const Shear6 &h)
00326 {
00327     xy = h.xy;
00328     xz = h.xz;
00329     yz = h.yz;
00330     yx = h.yx;
00331     zx = h.zx;
00332     zy = h.zy;
00333 }
00334 
00335 template <class T>
00336 template <class S>
00337 inline
00338 Shear6<T>::Shear6 (const Shear6<S> &h)
00339 {
00340     xy = T (h.xy);
00341     xz = T (h.xz);
00342     yz = T (h.yz);
00343     yx = T (h.yx);
00344     zx = T (h.zx);
00345     zy = T (h.zy);
00346 }
00347 
00348 template <class T>
00349 inline const Shear6<T> &
00350 Shear6<T>::operator = (const Shear6 &h)
00351 {
00352     xy = h.xy;
00353     xz = h.xz;
00354     yz = h.yz;
00355     yx = h.yx;
00356     zx = h.zx;
00357     zy = h.zy;
00358     return *this;
00359 }
00360 
00361 template <class T>
00362 template <class S>
00363 inline const Shear6<T> &
00364 Shear6<T>::operator = (const Vec3<S> &v)
00365 {
00366     xy = T (v.x);
00367     xz = T (v.y);
00368     yz = T (v.z);
00369     yx = 0;
00370     zx = 0;
00371     zy = 0;
00372     return *this;
00373 }
00374 
00375 template <class T>
00376 template <class S>
00377 inline void
00378 Shear6<T>::setValue (S XY, S XZ, S YZ, S YX, S ZX, S ZY)
00379 {
00380     xy = T (XY);
00381     xz = T (XZ);
00382     yz = T (YZ);
00383     yx = T (YX);
00384     zx = T (ZX);
00385     zy = T (ZY);
00386 }
00387 
00388 template <class T>
00389 template <class S>
00390 inline void
00391 Shear6<T>::setValue (const Shear6<S> &h)
00392 {
00393     xy = T (h.xy);
00394     xz = T (h.xz);
00395     yz = T (h.yz);
00396     yx = T (h.yx);
00397     zx = T (h.zx);
00398     zy = T (h.zy);
00399 }
00400 
00401 template <class T>
00402 template <class S>
00403 inline void
00404 Shear6<T>::getValue (S &XY, S &XZ, S &YZ, S &YX, S &ZX, S &ZY) const
00405 {
00406     XY = S (xy);
00407     XZ = S (xz);
00408     YZ = S (yz);
00409     YX = S (yx);
00410     ZX = S (zx);
00411     ZY = S (zy);
00412 }
00413 
00414 template <class T>
00415 template <class S>
00416 inline void
00417 Shear6<T>::getValue (Shear6<S> &h) const
00418 {
00419     h.xy = S (xy);
00420     h.xz = S (xz);
00421     h.yz = S (yz);
00422     h.yx = S (yx);
00423     h.zx = S (zx);
00424     h.zy = S (zy);
00425 }
00426 
00427 template <class T>
00428 inline T *
00429 Shear6<T>::getValue()
00430 {
00431     return (T *) &xy;
00432 }
00433 
00434 template <class T>
00435 inline const T *
00436 Shear6<T>::getValue() const
00437 {
00438     return (const T *) &xy;
00439 }
00440 
00441 template <class T>
00442 template <class S>
00443 inline bool
00444 Shear6<T>::operator == (const Shear6<S> &h) const
00445 {
00446     return xy == h.xy  &&  xz == h.xz  &&  yz == h.yz  &&  
00447            yx == h.yx  &&  zx == h.zx  &&  zy == h.zy;
00448 }
00449 
00450 template <class T>
00451 template <class S>
00452 inline bool
00453 Shear6<T>::operator != (const Shear6<S> &h) const
00454 {
00455     return xy != h.xy  ||  xz != h.xz  ||  yz != h.yz  ||
00456            yx != h.yx  ||  zx != h.zx  ||  zy != h.zy;
00457 }
00458 
00459 template <class T>
00460 bool
00461 Shear6<T>::equalWithAbsError (const Shear6<T> &h, T e) const
00462 {
00463     for (int i = 0; i < 6; i++)
00464         if (!Imath::equalWithAbsError ((*this)[i], h[i], e))
00465             return false;
00466 
00467     return true;
00468 }
00469 
00470 template <class T>
00471 bool
00472 Shear6<T>::equalWithRelError (const Shear6<T> &h, T e) const
00473 {
00474     for (int i = 0; i < 6; i++)
00475         if (!Imath::equalWithRelError ((*this)[i], h[i], e))
00476             return false;
00477 
00478     return true;
00479 }
00480 
00481 
00482 template <class T>
00483 inline const Shear6<T> &
00484 Shear6<T>::operator += (const Shear6 &h)
00485 {
00486     xy += h.xy;
00487     xz += h.xz;
00488     yz += h.yz;
00489     yx += h.yx;
00490     zx += h.zx;
00491     zy += h.zy;
00492     return *this;
00493 }
00494 
00495 template <class T>
00496 inline Shear6<T>
00497 Shear6<T>::operator + (const Shear6 &h) const
00498 {
00499     return Shear6 (xy + h.xy, xz + h.xz, yz + h.yz,
00500                    yx + h.yx, zx + h.zx, zy + h.zy);
00501 }
00502 
00503 template <class T>
00504 inline const Shear6<T> &
00505 Shear6<T>::operator -= (const Shear6 &h)
00506 {
00507     xy -= h.xy;
00508     xz -= h.xz;
00509     yz -= h.yz;
00510     yx -= h.yx;
00511     zx -= h.zx;
00512     zy -= h.zy;
00513     return *this;
00514 }
00515 
00516 template <class T>
00517 inline Shear6<T>
00518 Shear6<T>::operator - (const Shear6 &h) const
00519 {
00520     return Shear6 (xy - h.xy, xz - h.xz, yz - h.yz,
00521                    yx - h.yx, zx - h.zx, zy - h.zy);
00522 }
00523 
00524 template <class T>
00525 inline Shear6<T>
00526 Shear6<T>::operator - () const
00527 {
00528     return Shear6 (-xy, -xz, -yz, -yx, -zx, -zy);
00529 }
00530 
00531 template <class T>
00532 inline const Shear6<T> &
00533 Shear6<T>::negate ()
00534 {
00535     xy = -xy;
00536     xz = -xz;
00537     yz = -yz;
00538     yx = -yx;
00539     zx = -zx;
00540     zy = -zy;
00541     return *this;
00542 }
00543 
00544 template <class T>
00545 inline const Shear6<T> &
00546 Shear6<T>::operator *= (const Shear6 &h)
00547 {
00548     xy *= h.xy;
00549     xz *= h.xz;
00550     yz *= h.yz;
00551     yx *= h.yx;
00552     zx *= h.zx;
00553     zy *= h.zy;
00554     return *this;
00555 }
00556 
00557 template <class T>
00558 inline const Shear6<T> &
00559 Shear6<T>::operator *= (T a)
00560 {
00561     xy *= a;
00562     xz *= a;
00563     yz *= a;
00564     yx *= a;
00565     zx *= a;
00566     zy *= a;
00567     return *this;
00568 }
00569 
00570 template <class T>
00571 inline Shear6<T>
00572 Shear6<T>::operator * (const Shear6 &h) const
00573 {
00574     return Shear6 (xy * h.xy, xz * h.xz, yz * h.yz, 
00575                    yx * h.yx, zx * h.zx, zy * h.zy);
00576 }
00577 
00578 template <class T>
00579 inline Shear6<T>
00580 Shear6<T>::operator * (T a) const
00581 {
00582     return Shear6 (xy * a, xz * a, yz * a,
00583                    yx * a, zx * a, zy * a);
00584 }
00585 
00586 template <class T>
00587 inline const Shear6<T> &
00588 Shear6<T>::operator /= (const Shear6 &h)
00589 {
00590     xy /= h.xy;
00591     xz /= h.xz;
00592     yz /= h.yz;
00593     yx /= h.yx;
00594     zx /= h.zx;
00595     zy /= h.zy;
00596     return *this;
00597 }
00598 
00599 template <class T>
00600 inline const Shear6<T> &
00601 Shear6<T>::operator /= (T a)
00602 {
00603     xy /= a;
00604     xz /= a;
00605     yz /= a;
00606     yx /= a;
00607     zx /= a;
00608     zy /= a;
00609     return *this;
00610 }
00611 
00612 template <class T>
00613 inline Shear6<T>
00614 Shear6<T>::operator / (const Shear6 &h) const
00615 {
00616     return Shear6 (xy / h.xy, xz / h.xz, yz / h.yz,
00617                    yx / h.yx, zx / h.zx, zy / h.zy);
00618 }
00619 
00620 template <class T>
00621 inline Shear6<T>
00622 Shear6<T>::operator / (T a) const
00623 {
00624     return Shear6 (xy / a, xz / a, yz / a,
00625                    yx / a, zx / a, zy / a);
00626 }
00627 
00628 
00629 //-----------------------------
00630 // Stream output implementation
00631 //-----------------------------
00632 
00633 template <class T>
00634 std::ostream &
00635 operator << (std::ostream &s, const Shear6<T> &h)
00636 {
00637     return s << '(' 
00638              << h.xy << ' ' << h.xz << ' ' << h.yz 
00639              << h.yx << ' ' << h.zx << ' ' << h.zy 
00640              << ')';
00641 }
00642 
00643 
00644 //-----------------------------------------
00645 // Implementation of reverse multiplication
00646 //-----------------------------------------
00647 
00648 template <class S, class T>
00649 inline Shear6<T>
00650 operator * (S a, const Shear6<T> &h)
00651 {
00652     return Shear6<T> (a * h.xy, a * h.xz, a * h.yz,
00653                       a * h.yx, a * h.zx, a * h.zy);
00654 }
00655 
00656 
00657 } // namespace Imath
00658 
00659 #endif