Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
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
00140
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
00164
00165
00166
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