line3.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: line3.h,v 1.48 2004/07/05 20:57:28 oliver Exp $
00005 //
00006 
00007 #ifndef BALL_MATHS_LINE3_H
00008 #define BALL_MATHS_LINE3_H
00009 
00010 #ifndef BALL_COMMON_EXCEPTION_H
00011 # include <BALL/COMMON/exception.h>
00012 #endif
00013 
00014 #ifndef BALL_MATHS_VECTOR3_H
00015 # include <BALL/MATHS/vector3.h>
00016 #endif
00017 
00018 namespace BALL 
00019 {
00026 
00027   template <typename T>
00028   class TLine3;
00029   
00034   template <typename T>
00035   std::ostream& operator << (std::ostream& s, const TLine3<T>& line)
00036     ;
00037 
00038   template <typename T>
00039   std::istream& operator >> (std::istream& s, TLine3<T>& line)
00040     ;
00042   
00045   template <typename T>
00046   class TLine3
00047   {
00048     public:
00049 
00050     BALL_CREATE(TLine3<T>)
00051 
00052     
00055 
00060     enum Form
00061     {
00062       FORM__PARAMETER  = 0,
00063       FORM__TWO_POINTS = 1
00064     };
00066 
00070 
00073     TLine3()
00074       
00075       : p(),
00076         d()
00077     {
00078     }
00079 
00084     TLine3(const TLine3& line)
00085       
00086       : p(line.p),
00087         d(line.d)
00088     {
00089     }
00090 
00091     // form: PARAMETER (default) or TWO_POINTS
00092 
00102     TLine3(const TVector3<T>& point, const TVector3<T>& vector, Form form = FORM__PARAMETER)
00103       
00104       : p(point),
00105         d((form == FORM__PARAMETER) 
00106           ? vector 
00107           : vector - point)
00108     {
00109     }
00110 
00115     virtual ~TLine3()
00116       
00117     {
00118     }
00119 
00123     virtual void clear() 
00124       
00125     {
00126       p.clear();
00127       d.clear();
00128     }
00129 
00131 
00135 
00139     void swap(TLine3& line)
00140       
00141     {
00142       TVector3<T> temp_point(p);
00143       p = line.p;
00144       line.p = temp_point;
00145 
00146       TVector3<T> temp_vector(d);
00147       d = line.d;
00148       line.d = temp_vector;
00149     }
00150 
00154     void set(const TLine3& line)
00155       
00156     {
00157       p = line.p;
00158       d = line.d;
00159     }
00160 
00167     void set(const TVector3<T>& point, const TVector3<T>& vector, Form form = FORM__PARAMETER)
00168       
00169     {
00170       p = point;
00171       if (form == FORM__PARAMETER) 
00172       {
00173         d = vector;
00174       }
00175       else 
00176       {
00177         d = vector - point;
00178       }
00179     }
00180 
00185     TLine3& operator = (const TLine3& line)
00186       
00187     {
00188       p = line.p;
00189       d = line.d;
00190 
00191       return *this;
00192     }
00193 
00198     void get(TLine3& line) const 
00199     {
00200       line.p = p;
00201       line.d = d;
00202     }
00203 
00212     void get(TVector3<T>& point,TVector3<T>& vector, Form form = FORM__PARAMETER) const
00213       
00214     {
00215       point = p;
00216       if (form == FORM__PARAMETER) 
00217       {
00218         vector = d;
00219       }
00220       else 
00221       {
00222         vector - point = d;
00223       }
00224     }
00225 
00227 
00231 
00237     void normalize()
00238       
00239     {
00240       d.normalize();
00241     }
00243 
00247 
00251     bool operator == (const TLine3& line) const
00252       
00253     {
00254       return (p == line.p && d == line.d);
00255     }
00256 
00260     bool operator != (const TLine3& line) const
00261       
00262     {
00263       return (p != line.p || d != line.d);
00264     }
00265 
00269     bool has(const TVector3<T>& point) const
00270       
00271     {
00272       if (Maths::isNotZero(d.x))
00273       {
00274         T c = (point.x - p.x) / d.x;
00275 
00276         return (Maths::isEqual(p.y + c * d.y, point.y) && Maths::isEqual(p.z + c * d.z, point.z));
00277       }
00278       else 
00279       {
00280         if (Maths::isNotZero(d.y))
00281         {
00282           T c = (point.y - p.y) / d.y;
00283 
00284           return (Maths::isEqual(p.x, point.x)   // invariant: d.x == 0
00285                         && Maths::isEqual(p.z + c * d.z, point.z));
00286         }
00287         else 
00288         {
00289           if (Maths::isNotZero(d.z))
00290           {
00291             return (Maths::isEqual(p.x, point.x)   // invariant: d.x == 0
00292                           && Maths::isEqual(p.y, point.y)); // invariant: d.y == 0
00293           }
00294           else 
00295           {
00296             return false;
00297           }
00298         }
00299       }
00300     }
00301 
00303 
00306 
00311     bool isValid() const
00312       
00313     {
00314       return true;
00315     }
00316 
00323     void dump(std::ostream& s = std::cout, Size depth = 0) const
00324       
00325     {
00326       BALL_DUMP_STREAM_PREFIX(s);
00327 
00328       BALL_DUMP_HEADER(s, this, this);
00329 
00330       BALL_DUMP_DEPTH(s, depth);
00331       s << "  position: " << p << std::endl;
00332 
00333       BALL_DUMP_DEPTH(s, depth);
00334       s << "  direction: " << d << std::endl;
00335 
00336       BALL_DUMP_STREAM_SUFFIX(s);
00337     }
00339 
00340 
00344 
00347     TVector3<T> p;
00348 
00351     TVector3<T> d;
00353   };
00355 
00359   typedef TLine3<float> Line3;
00360 
00365   template <typename T>
00366   std::istream& operator >> (std::istream& s, TLine3<T>& line)
00367     
00368   {
00369     char c;
00370     s >> c >> line.p >> line.d >> c;
00371     return s;
00372   }
00373 
00381   template <typename T>
00382   std::ostream& operator << (std::ostream& s, const TLine3<T>& line)
00383     
00384   {
00385     s << '(' << line.p << ' ' << line.d << ')';
00386     return s;
00387   }
00388 } // namespace BALL
00389 
00390 #endif // BALL_MATHS_LINE3_H