00001
00002
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
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 }
00404
00405 #endif // BALL_MATHS_PLANE3_H