Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://visualizationlibrary.org */ 00005 /* */ 00006 /* Copyright (c) 2005-2010, Michele Bosi */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without modification, */ 00010 /* are permitted provided that the following conditions are met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, this */ 00013 /* list of conditions and the following disclaimer. */ 00014 /* */ 00015 /* - Redistributions in binary form must reproduce the above copyright notice, this */ 00016 /* list of conditions and the following disclaimer in the documentation and/or */ 00017 /* other materials provided with the distribution. */ 00018 /* */ 00019 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ 00020 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ 00021 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00022 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ 00023 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ 00024 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00025 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ 00026 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ 00027 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ 00028 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00029 /* */ 00030 /**************************************************************************************/ 00031 00032 #ifndef Sphere_INCLUDE_ONCE 00033 #define Sphere_INCLUDE_ONCE 00034 00035 #include <vlCore/AABB.hpp> 00036 00037 namespace vl 00038 { 00039 //----------------------------------------------------------------------------- 00040 // Sphere 00041 //----------------------------------------------------------------------------- 00043 class VLCORE_EXPORT Sphere 00044 { 00045 public: 00047 Sphere(): mRadius(-1) { } 00048 00050 Sphere(const vec3& center, real radius): mCenter(center), mRadius(radius) {} 00051 00053 Sphere(const AABB& aabb) { *this = aabb; } 00054 00056 void setNull() { mRadius =-1.0f; mCenter = vec3(0,0,0); } 00057 00059 bool isNull() const { return mRadius < 0.0f; } 00060 00062 bool isPoint() const { return mRadius == 0.0f; } 00063 00065 void setCenter(const vec3& center) { mCenter = center; } 00066 00068 const vec3& center() const { return mCenter; } 00069 00071 void setRadius( real radius ) { mRadius = radius; } 00072 00074 real radius() const { return mRadius; } 00075 00077 bool includes(const Sphere& other) const 00078 { 00079 if (isNull()) 00080 return false; 00081 else 00082 if (other.isNull()) 00083 return true; 00084 else 00085 { 00086 real distance = (center() - other.center()).length(); 00087 return radius() >= distance + other.radius(); 00088 } 00089 } 00090 00092 bool operator==(const Sphere& other) const 00093 { 00094 return mCenter == other.mCenter && mRadius == other.mRadius; 00095 } 00096 00098 bool operator!=(const Sphere& other) const 00099 { 00100 return !operator==(other); 00101 } 00102 00104 Sphere& operator=(const AABB& aabb) 00105 { 00106 if (aabb.isNull()) 00107 setNull(); 00108 else 00109 { 00110 mCenter = aabb.center(); 00111 mRadius = (aabb.minCorner() - aabb.maxCorner()).length() / (real)2.0; 00112 } 00113 return *this; 00114 } 00115 00117 Sphere operator+(const Sphere& other) 00118 { 00119 Sphere t = *this; 00120 return t += other; 00121 } 00122 00124 const Sphere& operator+=(const Sphere& other) 00125 { 00126 if (this->isNull()) 00127 *this = other; 00128 else 00129 if (other.includes(*this)) 00130 { 00131 *this = other; 00132 } 00133 else 00134 if (!other.isNull() && !this->includes(other)) 00135 { 00136 vec3 v = other.center() - this->center(); 00137 if (v.isNull()) 00138 { 00139 // the center remains the same 00140 // sets the maximum radius 00141 setRadius( radius() > other.radius() ? radius() : other.radius() ); 00142 } 00143 else 00144 { 00145 v.normalize(); 00146 vec3 p0 = this->center() - v * this->radius(); 00147 vec3 p1 = other.center() + v * other.radius(); 00148 setCenter( (p0 + p1)*(real)0.5 ); 00149 setRadius( (p0 - p1).length()*(real)0.5 ); 00150 } 00151 } 00152 00153 return *this; 00154 } 00155 00157 void transformed(Sphere& out, const mat4& mat) const 00158 { 00159 out.setNull(); 00160 if ( !isNull() ) 00161 { 00162 out.mCenter = mat * center(); 00163 // vec3 p = center() + vec3( (real)0.577350269189625840, (real)0.577350269189625840, (real)0.577350269189625840 ) * radius(); 00164 // p = mat * p; 00165 // p = p - out.center(); 00166 // out.setRadius(p.length()); 00167 vec3 p0 = center() + vec3(radius(),0,0); 00168 vec3 p1 = center() + vec3(0,radius(),0); 00169 vec3 p2 = center() + vec3(0,0,radius()); 00170 p0 = mat * p0; 00171 p1 = mat * p1; 00172 p2 = mat * p2; 00173 real d0 = (p0 - out.mCenter).lengthSquared(); 00174 real d1 = (p1 - out.mCenter).lengthSquared(); 00175 real d2 = (p2 - out.mCenter).lengthSquared(); 00176 out.mRadius = ::sqrt( d0>d1 ? (d0>d2?d0:d2) : (d1>d2?d1:d2) ); 00177 } 00178 } 00179 00181 Sphere transformed(const mat4& mat) const 00182 { 00183 Sphere sphere; 00184 transformed(sphere, mat); 00185 return sphere; 00186 } 00187 00188 protected: 00189 vec3 mCenter; 00190 real mRadius; 00191 }; 00192 } 00193 00194 #endif