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

point2.H

Go to the documentation of this file.
00001 #ifndef POINT2_H_IS_INCLUDED
00002 #define POINT2_H_IS_INCLUDED
00003 
00004 /*!
00005  *  \file Point2.H
00006  *  \brief Contains the declarations of the Point2 and Point2list classes.
00007  *  \ingroup group_MLIB
00008  *
00009  */
00010 
00011 #include <cmath>
00012 
00013 #include "mlib/pointlist.H"
00014 #include "std/support.H"
00015 #include "mlib/vec2.H"
00016 
00017 namespace mlib {
00018 
00019 /*!
00020  *  \brief A 2D point class with double precision floating point elements.
00021  *  \ingroup group_MLIB
00022  *
00023  *  This class is designed to be base class of more specific types of 2D points.
00024  *  Specifically, 2D points in different coordinate systems.  The template
00025  *  argument P is the type of the derived point class.  This allows the Point2 to
00026  *  return new points of the same type as the derived class.  The template
00027  *  argument V is the type of the corresponding 2D vector class for the
00028  *  coordinate system of the derived 2D point class.
00029  *
00030  */
00031 template <class P, class V>
00032 class Point2 {
00033    
00034    protected:
00035    
00036       double _x, _y;
00037 
00038    public:
00039    
00040       //! \name Constructors
00041       //@{
00042 
00043       //! \brief Default constructor.  Creates a point at the origin.
00044       Point2()                     : _x(0),    _y(0)    {}
00045       //! \brief Constructor that creates a point with the supplied double
00046       //! argumetn value in all components.
00047       explicit Point2(double s)    : _x(s),    _y(s)    {}
00048       //! \brief Construtor that creates a point with the components supplied in
00049       //! the arguments.
00050       Point2(double xx, double yy) : _x(xx),   _y(yy)   {}
00051       
00052       //@}
00053       
00054       //! \name Descriptive interface
00055       //@{
00056          
00057       typedef double value_type;
00058       static int dim() { return 2; }
00059       
00060       //@} 
00061       
00062       //! \name Element Access Functions
00063       //@{
00064    
00065       //! \brief Returns the elements of the point as an array.
00066       const double *data()               const { return &_x; }
00067       
00068       double   operator [](int index)    const { return (&_x)[index];     }
00069       double&  operator [](int index)          { return (&_x)[index];     }
00070       
00071       //@}
00072       
00073       //! \name Overloaded Arithmetic Operators
00074       //@{
00075       
00076       //! \brief Adds a point to a point.
00077       //! \warning This should only be used to add points that have already been
00078       //! pre-weighted by coefficients that add up to 1.
00079       P        operator  +(const P &p)   const { return P(_x+p[0],_y+p[1]);}
00080       P        operator  +(const V &v)   const { return P(_x+v[0],_y+v[1]);}
00081       V        operator  -(const P &p)   const { return V(_x-p[0],_y-p[1]);}
00082       P        operator  -(const V &v)   const { return P(_x-v[0],_y-v[1]);}
00083       P        operator  -()             const { return P(-_x,   -_y);     }
00084    
00085       P        operator  *(double    s)  const { return P(_x*s, _y*s); }
00086       P        operator  /(double    s)  const { return P(_x/s, _y/s); }
00087        
00088       //! \brief Component-wise multiplcation.
00089       P        operator  *(const P &p)   const { return P(_x*p[0],_y*p[1]);}
00090       //! \brief Component-wise multiplication.
00091       void     operator  *=(const P &p)  const { _x *= p[0]; _y *= p[1];   }
00092       
00093       //! \brief Adds a point to a point.
00094       //! \warning This should only be used to add points that have already been
00095       //! pre-weighted by coefficients that add up to 1.
00096       void     operator +=(const P &p)         { _x += p[0]; _y += p[1];     }
00097       void     operator +=(const V &v)         { _x += v[0]; _y += v[1];     }
00098       //! \question Should this function be allowed (subtracting two points and
00099       //! getting a point as the result)?
00100       void     operator -=(const P &p)         { _x -= p[0]; _y -= p[1];     }
00101       void     operator -=(const V &v)         { _x -= v[0]; _y -= v[1];     }
00102       void     operator *=(double scalar)      { _x *= scalar; _y *= scalar; }
00103       void     operator /=(double scalar)      { _x /= scalar; _y /= scalar; }
00104       
00105       //@}
00106       
00107       //! \name Overloaded Comparison Operators
00108       //@{
00109       
00110       //! \brief Are the two points exactly equal (component-wise)?
00111       bool     operator ==(const P &p)   const { return _x == p._x && _y == p._y;}
00112       //! \brief Are the two points not equal (component-wise)?
00113       bool     operator !=(const P &p)   const { return _x != p._x || _y != p._y;}
00114       
00115       //@}
00116       
00117       //! \name Point Property Queries
00118       //@{
00119    
00120       //! \brief Compute the distance from the point to the origin.
00121       //! \question Do we need/want this function (since points don't really
00122       //! have a length)?
00123       double   length     ()             const { return sqrt(_x*_x+_y*_y); }
00124       //! \brief Compute the distance squared from the point to the origin.
00125       //! \question Do we need/want this function (since points don't really
00126       //! have a length)?
00127       double   length_sqrd ()             const { return _x*_x+_y*_y;       }
00128       
00129       //@}
00130       
00131       //! \name Two Point Operations
00132       //@{
00133    
00134       //! \brief Compute the distance squared between two points.
00135       double   dist_sqrd   (const P &p)   const { return (_x-p._x) * (_x-p._x) + 
00136                                                     (_y-p._y) * (_y-p._y);  }
00137       //! \brief Compute the distance between two points.
00138       double   dist       (const P &p)   const { return sqrt(dist_sqrd(p)); }
00139       
00140       //@}
00141       
00142       //! \name Point Comparison Functions
00143       //@{
00144    
00145       //! \brief Is the distance between the two points essentially zero?
00146       bool     is_equal    (const P &p, double epsSqrd = epsAbsSqrdMath()) const 
00147          { return dist_sqrd(p) <= epsSqrd; }
00148          
00149       //@}
00150 
00151 }; // class Point2
00152 
00153 } // namespace mlib
00154 
00155 /* ---------- inlined global functions using Point2 template ------ */
00156 
00157 namespace mlib {
00158 
00159 //! \brief Stream instertion operator for Point2's.
00160 //! \relates Point2
00161 template <class P, class V>
00162 inline ostream &
00163 operator <<(ostream &os, const Point2<P,V> &p) 
00164 { 
00165    return os << "< " << p[0] << " " << p[1] << " >"; 
00166 }
00167 
00168 //! \brief Computes the determinant of the 2x2 matrix with the components of the
00169 //! points as rows.
00170 //! \relates Point2
00171 template <class P, class V>
00172 inline double det(const Point2<P,V> &a, const Point2<P,V> &b)
00173 {
00174    return (a[0] * b[1] - a[1] * b[0]);
00175 }
00176 
00177 } // namespace mlib
00178 
00179 namespace mlib {
00180 
00181 /*!
00182  *  \brief A class containing a list of Point2's.  Contains functions to aid in
00183  *  using this list of points as a piecewise continuous curve in some 2D
00184  *  coordinate system.
00185  *
00186  *  Like the Point2 class, Point2list is designed to be the base class for more
00187  *  specific types of lists of 2D points.  Specifically, lists of 2D points in
00188  *  different coordinate systems.  The template argument L is the type of the
00189  *  derived point list class.  This allows the Point2list to return new lists of
00190  *  the same type as the derived class.  The template arguments P, V, and S
00191  *  are the types of the corresponding point, vector and line classes
00192  *  (respectively) for the coordinate system of the derived 2D point list class.
00193  *
00194  */
00195 template <class L,class P,class V,class S>
00196 class Point2list : public Pointlist<L,P,V,S> {
00197 
00198    public:
00199    
00200       //! \name Constructors
00201       //@{
00202  
00203       //! \brief Construct a list with no points but space for m points
00204       Point2list(int m=16) : Pointlist<L,P,V,S>(m) { }
00205       
00206       //! \brief Construct a list using the passed in array of points
00207       Point2list(const ARRAY<P> &p) : Pointlist<L,P,V,S>(p) { }
00208       
00209       //@}
00210       
00211       //! \name Point List Property Queries
00212       //@{
00213       
00214       //! \brief Returns the winding number.
00215       //! 
00216       //! I.e.,computes the number of times the polyline winds around the given
00217       //! point in the CCW direction. For a closed polyline the result is
00218       //! an integer: e.g. +1 if it winds around once CCW, -1 if
00219       //! it winds once clockwise, and 0 if the given point is
00220       //! outside the projected polyline.
00221       double winding_number(const P&) const;
00222       
00223       //@}
00224       
00225       //! \name Intersection Testing Functions
00226       //@{
00227       
00228       //! \brief Returns true if any segment of the polyline crosses
00229       //! the line.
00230       bool intersects_line(const S& line) const;
00231       
00232       //! \brief Returns true if any segment of the polyline crosses
00233       //! the given line segment.
00234       bool intersects_seg(const S& segment) const;
00235       
00236       int     contains(const Point2list<L,P,V,S> &list)             const;
00237       int     contains(const P &p)                                  const;
00238       bool    ray_intersect(const P &p,const V &d,P &hit,int loop=0)const;
00239       bool    ray_intersect(const P &p,const V &d,L &hit,int loop=0)const;
00240       P       ray_intersect(const P &p,const V &d,int k0,int k1)    const;
00241       
00242       //@}
00243       
00244       //! \name List Operations
00245       //@{
00246       
00247       //! \brief Adjust this polyline so that it runs from a to b
00248       //! (uses a combination of translation, rotation, and scaling).
00249       void    fix_endpoints      (P a, P b);
00250       
00251       //@}
00252 
00253       using Pointlist<L,P,V,S>::num;
00254       using Pointlist<L,P,V,S>::first;
00255       using Pointlist<L,P,V,S>::last;
00256       using Pointlist<L,P,V,S>::pt;
00257       using Pointlist<L,P,V,S>::seg;
00258 
00259 };
00260 
00261 } // namespace mlib
00262  
00263 #ifdef JOT_NEEDS_TEMPLATES_IN_H_FILE
00264 #include "point2.C"
00265 #endif
00266 #endif // POINT2_H_IS_INCLUDED
00267 
00268 /* end of file Point2.H */

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