00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_MATHS_PLANE3_H
00008 #define BALL_MATHS_PLANE3_H
00009
00010 #ifdef BALL_HAS_IEEEFP_H
00011 # include <ieeefp.h>
00012 #endif
00013
00014 #include <math.h>
00015 #include <iostream>
00016
00017 #ifndef BALL_MATHS_LINE3_H
00018 # include <BALL/MATHS/line3.h>
00019 #endif
00020
00021 #ifndef BALL_MATHS_VECTOR3_H
00022 # include <BALL/MATHS/vector3.h>
00023 #endif
00024
00025 #ifndef BALL_MATHS_COMMON_H
00026 # include <BALL/MATHS/common.h>
00027 #endif
00028
00029 namespace BALL
00030 {
00035
00036 template <typename T>
00037 class TPlane3;
00038
00043 template <typename T>
00044 std::istream& operator >> (std::istream& s, TPlane3<T>& plane);
00045
00046 template <typename T>
00047 std::ostream& operator << (std::ostream& s, const TPlane3<T>& plane);
00049
00053 template <typename T>
00054 class TPlane3
00055 {
00056 public:
00057
00058 BALL_CREATE(TPlane3<T>)
00059
00060
00063
00068 TPlane3()
00069
00070 : p(),
00071 n()
00072 {
00073 }
00074
00079 TPlane3(const TPlane3& plane)
00080
00081 : p(plane.p),
00082 n(plane.n)
00083 {
00084 }
00085
00091 TPlane3(const TVector3<T>& point, const TVector3<T>& normal)
00092
00093 : p(point),
00094 n(normal)
00095 {
00096 }
00097
00103 TPlane3(const TVector3<T>& a, const TVector3<T>& b, const TVector3<T>& c)
00104
00105 : p(a),
00106 n((a - b) % (b - c))
00107 {
00108 }
00109
00115 TPlane3(const T& a, const T& b, const T& c, const T& d)
00116 throw(Exception::DivisionByZero)
00117 {
00118 n = TVector3<T>(a, b, c);
00119 if (a == 0 && b == 0 && c == 0)
00120 {
00121 throw Exception::DivisionByZero(__FILE__, __LINE__);
00122 }
00123 if (!Maths::isZero(a))
00124 {
00125 p.set(-d / a, 0, 0);
00126 }
00127 else if (!Maths::isZero(b))
00128 {
00129 p.set(0, -d / b, 0);
00130 }
00131 else if (!Maths::isZero(c))
00132 {
00133 p.set(0, 0, -d / c);
00134 }
00135 }
00136
00141 virtual ~TPlane3()
00142
00143 {
00144 }
00145
00149 virtual void clear()
00150
00151 {
00152 n.clear();
00153 p.clear();
00154 }
00155
00157
00161
00163 void swap(TPlane3& plane)
00164 {
00165 TVector3<T> temp_point(p);
00166 p = plane.p;
00167 plane.p = temp_point;
00168
00169 temp_point = n;
00170 n = plane.n;
00171 plane.n = temp_point;
00172 }
00173
00178 void set(const TPlane3& plane)
00179
00180 {
00181 p = plane.p;
00182 n = plane.n;
00183 }
00184
00189 void set(const TVector3<T>& point, const TVector3<T>& normal)
00190
00191 {
00192 p = point;
00193 n = normal;
00194 }
00195
00201 void set(const TVector3<T>& a, const TVector3<T>& b, const TVector3<T>& c)
00202
00203 {
00204 p = a;
00205 n = (a - b) % (b - c);
00206 }
00207
00212 TPlane3& operator = (const TPlane3& plane)
00213
00214 {
00215 p = plane.p;
00216 n = plane.n;
00217
00218 return *this;
00219 }
00220
00225 void get(TPlane3& plane) const
00226
00227 {
00228 plane.p = p;
00229 plane.n = n;
00230 }
00231
00236 void get(TVector3<T>& point, TVector3<T>& normal) const
00237
00238 {
00239 point = p;
00240 normal = n;
00241 }
00243
00247
00253 void normalize()
00254 throw(Exception::DivisionByZero)
00255 {
00256 T length = n.getLength();
00257
00258 if (length == 0.0)
00259 {
00260 throw Exception::DivisionByZero(__FILE__, __LINE__);
00261 }
00262
00263 n /= length;
00264 }
00265
00272 void hessify()
00273
00274 {
00275 normalize();
00276 if (Maths::isLess(n * p, 0))
00277 {
00278 n.negate();
00279 }
00280 }
00281
00283
00287
00291 bool operator == (const TPlane3& plane) const
00292
00293 {
00294 return (p == plane.p && n == plane.n);
00295 }
00296
00300 bool operator != (const TPlane3& plane) const
00301
00302 {
00303 return (p != plane.p || n != plane.n);
00304 }
00305
00310 bool has(const TVector3<T>& point) const
00311
00312 {
00313 return Maths::isZero(n * (point - p));
00314 }
00315
00320 bool has(const TLine3<T>& line) const
00321
00322 {
00323 return (Maths::isZero(n * line.d) && has(line.p));
00324 }
00326
00330
00335 bool isValid() const
00336
00337 {
00338 return true;
00339 }
00340
00347 void dump(std::ostream& s = std::cout, Size depth = 0) const
00348
00349 {
00350 BALL_DUMP_STREAM_PREFIX(s);
00351
00352 BALL_DUMP_HEADER(s, this, this);
00353
00354 BALL_DUMP_DEPTH(s, depth);
00355 s << " position: " << p << std::endl;
00356
00357 BALL_DUMP_DEPTH(s, depth);
00358 s << " normal: " << n << std::endl;
00359
00360 BALL_DUMP_STREAM_SUFFIX(s);
00361 }
00363
00369 TVector3<T> p;
00370
00373 TVector3<T> n;
00374
00376 };
00378
00382 template <typename T>
00383 std::istream& operator >> (std::istream& s, TPlane3<T>& plane)
00384
00385 {
00386 char c;
00387 s >> c >> plane.p >> plane.n >> c;
00388 return s;
00389 }
00390
00394 template <typename T>
00395 std::ostream& operator << (std::ostream& s, const TPlane3<T>& plane)
00396
00397 {
00398 return (s << '(' << plane.p << ' ' << plane.n << ')');
00399 }
00400
00404 typedef TPlane3<float> Plane3;
00405
00406 }
00407
00408 #endif // BALL_MATHS_PLANE3_H