BALL  1.4.1
plane3.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines