1 /////////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas 4 // Digital Ltd. LLC 5 // 6 // All rights reserved. 7 // 8 // Redistribution and use in source and binary forms, with or without 9 // modification, are permitted provided that the following conditions are 10 // met: 11 // * Redistributions of source code must retain the above copyright 12 // notice, this list of conditions and the following disclaimer. 13 // * Redistributions in binary form must reproduce the above 14 // copyright notice, this list of conditions and the following disclaimer 15 // in the documentation and/or other materials provided with the 16 // distribution. 17 // * Neither the name of Industrial Light & Magic nor the names of 18 // its contributors may be used to endorse or promote products derived 19 // from this software without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 // 33 /////////////////////////////////////////////////////////////////////////// 34 35 36 37 #ifndef INCLUDED_IMATHSPHERE_H 38 #define INCLUDED_IMATHSPHERE_H 39 40 //------------------------------------- 41 // 42 // A 3D sphere class template 43 // 44 //------------------------------------- 45 46 #include "ImathVec.h" 47 #include "ImathBox.h" 48 #include "ImathLine.h" 49 50 namespace Imath { 51 52 template <class T> 53 class Sphere3 54 { 55 public: 56 57 Vec3<T> center; 58 T radius; 59 60 //--------------- 61 // Constructors 62 //--------------- 63 64 Sphere3() : center(0,0,0), radius(0) {} 65 Sphere3(const Vec3<T> &c, T r) : center(c), radius(r) {} 66 67 //------------------------------------------------------------------- 68 // Utilities: 69 // 70 // s.circumscribe(b) sets center and radius of sphere s 71 // so that the s tightly encloses box b. 72 // 73 // s.intersectT (l, t) If sphere s and line l intersect, then 74 // intersectT() computes the smallest t, 75 // t >= 0, so that l(t) is a point on the 76 // sphere. intersectT() then returns true. 77 // 78 // If s and l do not intersect, intersectT() 79 // returns false. 80 // 81 // s.intersect (l, i) If sphere s and line l intersect, then 82 // intersect() calls s.intersectT(l,t) and 83 // computes i = l(t). 84 // 85 // If s and l do not intersect, intersect() 86 // returns false. 87 // 88 //------------------------------------------------------------------- 89 90 void circumscribe(const Box<Vec3<T> > &box); 91 bool intersect(const Line3<T> &l, Vec3<T> &intersection) const; 92 bool intersectT(const Line3<T> &l, T &t) const; 93 }; 94 95 96 //-------------------- 97 // Convenient typedefs 98 //-------------------- 99 100 typedef Sphere3<float> Sphere3f; 101 typedef Sphere3<double> Sphere3d; 102 103 104 //--------------- 105 // Implementation 106 //--------------- 107 108 template <class T> 109 void Sphere3<T>::circumscribe(const Box<Vec3<T> > &box) 110 { 111 center = T(0.5) * (box.min + box.max); 112 radius = (box.max - center).length(); 113 } 114 115 116 template <class T> 117 bool Sphere3<T>::intersectT(const Line3<T> &line, T &t) const 118 { 119 bool doesIntersect = true; 120 121 Vec3<T> v = line.pos - center; 122 T B = T(2.0) * (line.dir ^ v); 123 T C = (v ^ v) - (radius * radius); 124 125 // compute discriminant 126 // if negative, there is no intersection 127 128 T discr = B*B - T(4.0)*C; 129 130 if (discr < 0.0) 131 { 132 // line and Sphere3 do not intersect 133 134 doesIntersect = false; 135 } 136 else 137 { 138 // t0: (-B - sqrt(B^2 - 4AC)) / 2A (A = 1) 139 140 T sqroot = Math<T>::sqrt(discr); 141 t = (-B - sqroot) * T(0.5); 142 143 if (t < 0.0) 144 { 145 // no intersection, try t1: (-B + sqrt(B^2 - 4AC)) / 2A (A = 1) 146 147 t = (-B + sqroot) * T(0.5); 148 } 149 150 if (t < 0.0) 151 doesIntersect = false; 152 } 153 154 return doesIntersect; 155 } 156 157 158 template <class T> 159 bool Sphere3<T>::intersect(const Line3<T> &line, Vec3<T> &intersection) const 160 { 161 T t; 162 163 if (intersectT (line, t)) 164 { 165 intersection = line(t); 166 return true; 167 } 168 else 169 { 170 return false; 171 } 172 } 173 174 175 } //namespace Imath 176 177 #endif 178