PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/ilmbase-1.0.2/ImathLine.h
00001 
00002 //
00003 // Copyright (c) 2002, 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_IMATHLINE_H
00038 #define INCLUDED_IMATHLINE_H
00039 
00040 //-------------------------------------
00041 //
00042 //      A 3D line class template
00043 //
00044 //-------------------------------------
00045 
00046 #include "ImathVec.h"
00047 #include "ImathLimits.h"
00048 #include "ImathMatrix.h"
00049 
00050 namespace Imath {
00051 
00052 
00053 template <class T>
00054 class Line3
00055 {
00056   public:
00057 
00058     Vec3<T>                     pos;
00059     Vec3<T>                     dir;
00060     
00061     //-------------------------------------------------------------
00062     //  Constructors - default is normalized units along direction
00063     //-------------------------------------------------------------
00064 
00065     Line3() {}
00066     Line3(const Vec3<T>& point1, const Vec3<T>& point2);
00067 
00068     //------------------
00069     //  State Query/Set
00070     //------------------
00071 
00072     void                        set(const Vec3<T>& point1, 
00073                                     const Vec3<T>& point2);
00074 
00075     //-------
00076     //  F(t)
00077     //-------
00078 
00079     Vec3<T>                     operator() (T parameter) const;
00080 
00081     //---------
00082     //  Query
00083     //---------
00084 
00085     T                           distanceTo(const Vec3<T>& point) const;
00086     T                           distanceTo(const Line3<T>& line) const;
00087     Vec3<T>                     closestPointTo(const Vec3<T>& point) const;
00088     Vec3<T>                     closestPointTo(const Line3<T>& line) const;
00089 };
00090 
00091 
00092 //--------------------
00093 // Convenient typedefs
00094 //--------------------
00095 
00096 typedef Line3<float> Line3f;
00097 typedef Line3<double> Line3d;
00098 
00099 
00100 //---------------
00101 // Implementation
00102 //---------------
00103 
00104 template <class T>
00105 inline Line3<T>::Line3(const Vec3<T> &p0, const Vec3<T> &p1)
00106 {
00107     set(p0,p1);
00108 }
00109 
00110 template <class T>
00111 inline void Line3<T>::set(const Vec3<T> &p0, const Vec3<T> &p1)
00112 {
00113     pos = p0; dir = p1-p0;
00114     dir.normalize();
00115 }
00116 
00117 template <class T>
00118 inline Vec3<T> Line3<T>::operator()(T parameter) const
00119 {
00120     return pos + dir * parameter;
00121 }
00122 
00123 template <class T>
00124 inline T Line3<T>::distanceTo(const Vec3<T>& point) const
00125 {
00126     return (closestPointTo(point)-point).length();
00127 }
00128 
00129 template <class T>
00130 inline Vec3<T> Line3<T>::closestPointTo(const Vec3<T>& point) const
00131 {
00132     return ((point - pos) ^ dir) * dir + pos;
00133 }
00134 
00135 template <class T>
00136 inline T Line3<T>::distanceTo(const Line3<T>& line) const
00137 {
00138     T d = (dir % line.dir) ^ (line.pos - pos);
00139     return (d >= 0)? d: -d;
00140 }
00141 
00142 template <class T>
00143 inline Vec3<T> 
00144 Line3<T>::closestPointTo(const Line3<T>& line) const
00145 {
00146     // Assumes the lines are normalized
00147 
00148     Vec3<T> posLpos = pos - line.pos ;
00149     T c = dir ^ posLpos;
00150     T a = line.dir ^ dir;
00151     T f = line.dir ^ posLpos ;
00152     T num = c - a * f;
00153 
00154     T denom = a*a - 1;
00155 
00156     T absDenom = ((denom >= 0)? denom: -denom);
00157 
00158     if (absDenom < 1)
00159     {
00160         T absNum = ((num >= 0)? num: -num);
00161 
00162         if (absNum >= absDenom * limits<T>::max())
00163             return pos;
00164     }
00165 
00166     return pos + dir * (num / denom);
00167 }
00168 
00169 template<class T>
00170 std::ostream& operator<< (std::ostream &o, const Line3<T> &line)
00171 {
00172     return o << "(" << line.pos << ", " << line.dir << ")";
00173 }
00174 
00175 template<class S, class T>
00176 inline Line3<S> operator * (const Line3<S> &line, const Matrix44<T> &M)
00177 {
00178     return Line3<S>( line.pos * M, (line.pos + line.dir) * M );
00179 }
00180 
00181 
00182 } // namespace Imath
00183 
00184 #endif