PBRT
|
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