plane3.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: plane3.h,v 1.38 2004/05/27 19:49:42 oliver Exp $
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       // throw an exception on zero length normal
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 } // namespace BALL
00407 
00408 #endif // BALL_MATHS_PLANE3_H