Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

plane.H

Go to the documentation of this file.
00001 #ifndef PLANE_H_IS_INCLUDED
00002 #define PLANE_H_IS_INCLUDED
00003 
00004 /*!
00005  *  \file Plane.H
00006  *  \brief Contains the definition of the Plane class.  A 3D oriented plane class.
00007  *  \ingroup group_MLIB
00008  *
00009  */
00010 
00011 #include "mlib/point2.H"
00012 #include "mlib/point3.H"
00013 
00014 namespace mlib {
00015 
00016 /*!
00017  *  \brief Declaration of a class plane, keeping a definition of an
00018  *   oriented plane in 3D.
00019  *  \ingroup group_MLIB
00020  *
00021  *  The plane is defined by its (unit) normal vector and parameter 'd', which is
00022  *  the signed distance of the plane from the origin of the coordinate system.
00023  *
00024  *  For all points on the plane holds:
00025  *
00026  *    normal * point + d = 0
00027  *
00028  *  The plane parameters are accessed via public accessor methods 'normal' and
00029  *  'd'.
00030  *
00031  *  If the plane is invalid (cannot be constructed), the plane
00032  *  normal is set to a null vector.
00033  *
00034 */
00035 template <class PLANE, class P, class V, class L>
00036 class Plane
00037 {
00038    
00039    protected:
00040    
00041       V       _normal;
00042       double  _d;
00043 
00044    public:
00045    
00046       //! \name Constructors
00047       //@{
00048 
00049       //! \brief Default constructor.  Creates a plane with a zero offset from
00050       //! the origin and default constructed vector.
00051       //!
00052       //! This most likely creates an invalid plane with a zero length vector.
00053       Plane()                     :                        _d(0) {}
00054       
00055       
00056       //! \brief Constructor that creates a plane with the normal and offset set
00057       //! to the values passed as arguments.
00058       Plane(const V &n, double d) : _normal(n.normalized()),_d(d) {}
00059       
00060       //! \brief Constructor that creates a plane that passes through the point
00061       //! \p p and that has normal \p n.
00062       Plane(const P &p, const V&n): _normal(n.normalized()),_d((P()-p)*_normal) {}
00063       
00064       //! \brief Constructor that creates a plane that contains the three points
00065       //! \p p1, \p p2 and \p p3.
00066       Plane(const P &p1,  const P&p2, const P&p3)  
00067          { *this = Plane<PLANE,P,V,L>(p1, cross(p3-p1, p2-p1)); }
00068       
00069       //! \brief Constructor that creates a plane that contains the given piont
00070       //! and two given vectors.
00071       Plane(const P &,  const V&, const V&);
00072       
00073       //! \brief Create plane from a polygon of vertices (n >=3).
00074       Plane(const P plg[], int n);
00075       
00076       //! \brief The plane normal is given, just calculate the 'd' parameter
00077       //! from all polygon vertices.
00078       Plane(const P plg[], int n, const V& normal);
00079       
00080       //@}
00081       
00082       //! \name Accessor Functions
00083       //@{
00084          
00085       V       &normal    ()                { return _normal; }
00086       const V &normal    ()          const { return _normal; }
00087       
00088       double  &d         ()                { return _d; }
00089       double   d         ()          const { return _d; }
00090          
00091       //@}
00092       
00093       //! \name Plane Property Queries
00094       //@{
00095       
00096       P        origin    ()          const { return P()-_normal*_d; }
00097       
00098       //! \brief Is the plane valid (i.e. does it have a unit length normal)?
00099       bool     is_valid   ()          const
00100          { return fabs(_normal.length() - 1) < epsNorMath(); }
00101          
00102       //@}
00103       
00104       //! \name Plane Comparison Functions
00105       //@{
00106       
00107       //! \brief Are the two planes parallel?
00108       bool     is_parallel(const PLANE &p) const
00109          { return _normal.is_equal(p._normal) || _normal.is_equal(-p._normal); }
00110          
00111       //! \brief Are the two planes equivalent?
00112       bool     is_equal   (const PLANE &p) const
00113          { return (_d*_normal).is_equal(p._d*p._normal);  }
00114          
00115       //@}
00116       
00117       //! \name Overloaded Arithmetic Operators
00118       //@{
00119       
00120       //! \brief Negates the plane's normal vector and offset.
00121       PLANE    operator -()          const { return PLANE(-_normal, -_d); }
00122       
00123       //@}
00124       
00125       //! \name Projection Functions
00126       //@{
00127       
00128       //! \brief Projects the given point on to the plane.
00129       P        project   (const P & )const;
00130       //! \brief Projects the given vector on to the plane.
00131       V        project   (const V & )const;
00132       //! \brief Projects the given line on to the plane.
00133       L        project   (const L & )const;
00134       
00135       //@}
00136       
00137       //! \brief Computes the distance from the given point to the nearest point
00138       //! on the plane.
00139       double   dist      (const P &p)const { return (p-P())*_normal+_d; }
00140       
00141       //! \brief Computes the intersection point of the given line and the plane.
00142       P        intersect(const L &l) const
00143          { return plane_intersect(l.point(), l.vector(), origin(), _normal); }
00144 
00145 }; // class Plane
00146 
00147 } // namespace mlib
00148 
00149 namespace mlib {
00150 
00151 //! \brief Computes the intersection of the ray defined by point \p pt and vector
00152 //! \p D and the plane defined by point \p O and normal vector \p N.
00153 //! \relates Plane
00154 template <class P, class V> 
00155 inline
00156 P        
00157 plane_intersect(
00158    const P &pt, 
00159    const V &D, 
00160    const P &O, 
00161    const V &N)
00162 {
00163    double t = (fabs(D*N) > 0.000001) ? ((O-pt) * N) / (D*N) : -1; 
00164 
00165    return pt + t * D; 
00166 }
00167 
00168 //! \relates Plane
00169 template <class P, class V> 
00170 inline
00171 double
00172 axis_ang( 
00173    const P &p1, 
00174    const P &p2, 
00175    const P &axispt, 
00176    const V &axis)
00177 {
00178    V v1 = (p1 - axispt).normalized();
00179    V v2 = (p2 - axispt).normalized();
00180    double ang = Acos(v1*v2);
00181    if (cross(v1,v2) * axis < 0)
00182       ang = -ang;
00183    return ang;
00184 }
00185 
00186 } // namespace mlib
00187 
00188 #ifdef JOT_NEEDS_TEMPLATES_IN_H_FILE
00189 #include "plane.C"
00190 #endif
00191 
00192 #endif // PLANE_H_IS_INCLUDED

Generated on Mon Sep 18 11:39:32 2006 for jot by  doxygen 1.4.4