BALL
1.4.1
|
00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 00003 // 00004 00005 #ifndef BALL_MATHS_PLANE3_H 00006 #define BALL_MATHS_PLANE3_H 00007 00008 #ifdef BALL_HAS_IEEEFP_H 00009 # include <ieeefp.h> 00010 #endif 00011 00012 #include <math.h> 00013 #include <iostream> 00014 00015 #ifndef BALL_MATHS_LINE3_H 00016 # include <BALL/MATHS/line3.h> 00017 #endif 00018 00019 #ifndef BALL_MATHS_VECTOR3_H 00020 # include <BALL/MATHS/vector3.h> 00021 #endif 00022 00023 #ifndef BALL_MATHS_COMMON_H 00024 # include <BALL/MATHS/common.h> 00025 #endif 00026 00027 namespace BALL 00028 { 00033 00034 template <typename T> 00035 class TPlane3; 00036 00041 template <typename T> 00042 std::istream& operator >> (std::istream& s, TPlane3<T>& plane); 00043 00044 template <typename T> 00045 std::ostream& operator << (std::ostream& s, const TPlane3<T>& plane); 00047 00051 template <typename T> 00052 class TPlane3 00053 { 00054 public: 00055 00056 BALL_CREATE(TPlane3<T>) 00057 00058 00061 00066 TPlane3() 00067 00068 : p(), 00069 n() 00070 { 00071 } 00072 00077 TPlane3(const TPlane3& plane) 00078 00079 : p(plane.p), 00080 n(plane.n) 00081 { 00082 } 00083 00089 TPlane3(const TVector3<T>& point, const TVector3<T>& normal) 00090 00091 : p(point), 00092 n(normal) 00093 { 00094 } 00095 00101 TPlane3(const TVector3<T>& a, const TVector3<T>& b, const TVector3<T>& c) 00102 00103 : p(a), 00104 n((a - b) % (b - c)) 00105 { 00106 } 00107 00114 TPlane3(const T& a, const T& b, const T& c, const T& d) 00115 { 00116 n = TVector3<T>(a, b, c); 00117 if (a == 0 && b == 0 && c == 0) 00118 { 00119 throw Exception::DivisionByZero(__FILE__, __LINE__); 00120 } 00121 if (!Maths::isZero(a)) 00122 { 00123 p.set(-d / a, 0, 0); 00124 } 00125 else if (!Maths::isZero(b)) 00126 { 00127 p.set(0, -d / b, 0); 00128 } 00129 else if (!Maths::isZero(c)) 00130 { 00131 p.set(0, 0, -d / c); 00132 } 00133 } 00134 00139 virtual ~TPlane3() 00140 00141 { 00142 } 00143 00147 virtual void clear() 00148 00149 { 00150 n.clear(); 00151 p.clear(); 00152 } 00153 00155 00159 00161 void swap(TPlane3& plane) 00162 { 00163 TVector3<T> temp_point(p); 00164 p = plane.p; 00165 plane.p = temp_point; 00166 00167 temp_point = n; 00168 n = plane.n; 00169 plane.n = temp_point; 00170 } 00171 00176 void set(const TPlane3& plane) 00177 00178 { 00179 p = plane.p; 00180 n = plane.n; 00181 } 00182 00187 void set(const TVector3<T>& point, const TVector3<T>& normal) 00188 00189 { 00190 p = point; 00191 n = normal; 00192 } 00193 00199 void set(const TVector3<T>& a, const TVector3<T>& b, const TVector3<T>& c) 00200 00201 { 00202 p = a; 00203 n = (a - b) % (b - c); 00204 } 00205 00210 TPlane3& operator = (const TPlane3& plane) 00211 00212 { 00213 p = plane.p; 00214 n = plane.n; 00215 00216 return *this; 00217 } 00218 00223 void get(TPlane3& plane) const 00224 00225 { 00226 plane.p = p; 00227 plane.n = n; 00228 } 00229 00234 void get(TVector3<T>& point, TVector3<T>& normal) const 00235 00236 { 00237 point = p; 00238 normal = n; 00239 } 00241 00245 00251 void normalize() 00252 { 00253 T length = n.getLength(); 00254 // throw an exception on zero length normal 00255 if (length == 0.0) 00256 { 00257 throw Exception::DivisionByZero(__FILE__, __LINE__); 00258 } 00259 00260 n /= length; 00261 } 00262 00269 void hessify() 00270 00271 { 00272 normalize(); 00273 if (Maths::isLess(n * p, 0)) 00274 { 00275 n.negate(); 00276 } 00277 } 00278 00280 00284 00288 bool operator == (const TPlane3& plane) const 00289 00290 { 00291 return (p == plane.p && n == plane.n); 00292 } 00293 00297 bool operator != (const TPlane3& plane) const 00298 00299 { 00300 return (p != plane.p || n != plane.n); 00301 } 00302 00307 bool has(const TVector3<T>& point) const 00308 00309 { 00310 return Maths::isZero(n * (point - p)); 00311 } 00312 00317 bool has(const TLine3<T>& line) const 00318 00319 { 00320 return (Maths::isZero(n * line.d) && has(line.p)); 00321 } 00323 00327 00332 bool isValid() const 00333 00334 { 00335 return true; 00336 } 00337 00344 void dump(std::ostream& s = std::cout, Size depth = 0) const 00345 00346 { 00347 BALL_DUMP_STREAM_PREFIX(s); 00348 00349 BALL_DUMP_HEADER(s, this, this); 00350 00351 BALL_DUMP_DEPTH(s, depth); 00352 s << " position: " << p << std::endl; 00353 00354 BALL_DUMP_DEPTH(s, depth); 00355 s << " normal: " << n << std::endl; 00356 00357 BALL_DUMP_STREAM_SUFFIX(s); 00358 } 00360 00366 TVector3<T> p; 00367 00370 TVector3<T> n; 00371 00373 }; 00375 00379 template <typename T> 00380 std::istream& operator >> (std::istream& s, TPlane3<T>& plane) 00381 00382 { 00383 char c; 00384 s >> c >> plane.p >> plane.n >> c; 00385 return s; 00386 } 00387 00391 template <typename T> 00392 std::ostream& operator << (std::ostream& s, const TPlane3<T>& plane) 00393 00394 { 00395 return (s << '(' << plane.p << ' ' << plane.n << ')'); 00396 } 00397 00401 typedef TPlane3<float> Plane3; 00402 00403 } // namespace BALL 00404 00405 #endif // BALL_MATHS_PLANE3_H