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

point3.H

Go to the documentation of this file.
00001 #ifndef POINT3_H_IS_INCLUDED
00002 #define POINT3_H_IS_INCLUDED
00003 
00004 /*!
00005  *  \file Point3.H
00006  *  \brief Contains the declarations of the Point3 and Point3list classes.
00007  *  \ingroup group_MLIB
00008  *
00009  */
00010 
00011 #include "mlib/pointlist.H"
00012 #include "mlib/mat4.H"
00013 #include "mlib/vec3.H"
00014 #include "mlib/line.H"
00015 #include "mlib/nearest_pt.H"
00016 #include "std/support.H"
00017 
00018 namespace mlib {
00019 
00020 /*!
00021  *  \brief A 3D point class with double precision floating point elements.
00022  *  \ingroup group_MLIB
00023  *
00024  *  This class is designed to be base class of more specific types of 3D points.
00025  *  Specifically, 3D points in different coordinate systems.  The template
00026  *  argument P is the type of the derived point class.  This allows the Point3 to
00027  *  return new points of the same type as the derived class.  The template
00028  *  argument V is the type of the corresponding 3D vector class for the
00029  *  coordinate system of the derived 3D point class.
00030  *
00031  *  \note Point3's can be added together using either the + operator or the
00032  *  % operator.  Both perform exactly the same operation. -- <b> This is not
00033  *  true anymore.  The % operator has been removed from this class. </b>
00034  *
00035  *  \todo Figure out why both the + operator and the % operator are used for
00036  *  point addition. -- \b Done
00037  *
00038  *  \todo Remove % operator in favor of + operator. -- \b Done
00039  *
00040  */
00041 template <typename P, typename V>
00042 class Point3 {
00043    
00044    protected:
00045    
00046       double _x, _y, _z;
00047 
00048    public:
00049    
00050       //! \name Constructors
00051       //@{   
00052    
00053       Point3()                             : _x(0),    _y(0),    _z(0)   {}
00054       explicit Point3(double s)            : _x(s),    _y(s),    _z(s)   {}
00055       Point3(double x, double y, double z) : _x(x),    _y(y),    _z(z)   {}
00056       
00057       //@}
00058       
00059       //! \name Descriptive interface
00060       //@{
00061          
00062       typedef double value_type;
00063       static int dim() { return 3; }
00064       
00065       //@} 
00066       
00067       //! \name Element Access Functions
00068       //@{
00069    
00070       void          set(double x, double y, double z)  { _x=x; _y=y; _z=z; }
00071       const double* data()            const{ return &_x; }
00072    
00073       double  operator [](int index)  const{ return (&_x)[index]; }
00074       double& operator [](int index)       { return (&_x)[index]; }
00075       
00076       //@}
00077       
00078       //! \name Overloaded Arithmetic Operators
00079       //@{
00080          
00081       P  operator  *(double s)        const{ return P(_x*s, _y*s, _z*s);}
00082       P  operator  /(double s)        const{ return P(_x/s, _y/s, _z/s);}
00083       //! \brief Adds a point to a point.
00084       //! \warning This should only be used to add points that have already been
00085       //! pre-weighted by coefficients that add up to 1.
00086       P  operator  +(const P& p)      const{ return P(_x+p[0], _y+p[1], _z+p[2]);}
00087       P  operator  +(const V& v)      const{ return P(_x+v[0], _y+v[1], _z+v[2]);}
00088       V  operator  -(const P& p)      const{ return V(_x-p[0], _y-p[1], _z-p[2]);}
00089       P  operator  -(const V& v)      const{ return P(_x-v[0], _y-v[1], _z-v[2]);}
00090       P  operator  -()                const{ return P(-_x, -_y, -_z);}
00091        
00092       //! \brief Adds a point to a point.
00093       //! \warning This should only be used to add points that have already been
00094       //! pre-weighted by coefficients that add up to 1.
00095       void    operator +=(const P& p)      { _x += p[0]; _y += p[1]; _z += p[2]; }
00096       void    operator +=(const V& v)      { _x += v[0]; _y += v[1]; _z += v[2]; }
00097       void    operator -=(const V& v)      { _x -= v[0]; _y -= v[1]; _z -= v[2]; }
00098       void    operator *=(double   s)      { _x *= s; _y *= s; _z *= s; }
00099       void    operator /=(double   s)      { _x /= s; _y /= s; _z /= s; }
00100       
00101       //@}
00102    
00103       //! \name Two Point Operations
00104       //@{
00105       
00106       //! \brief Computes the distance squared between two points.
00107       double dist_sqrd(const P& p) const
00108          { return sqr(_x-p._x) + sqr(_y-p._y) + sqr(_z-p._z); }
00109          
00110       //! \brief Computes the distance between two points.
00111       double  dist(const P& p) const { return sqrt(dist_sqrd(p)); }
00112       
00113       //@}
00114    
00115       //! \name Overloaded Comparison Operators
00116       //@{
00117       
00118       //! \brief Are the two points exactly equal (component wise)?
00119       bool operator ==(const P& p) const { return _x==p._x&&_y==p._y&&_z==p._z; }
00120       //! \brief Are the two points not equal (component wise)?
00121       bool operator !=(const P& p) const { return _x!=p._x||_y!=p._y||_z!=p._z; }
00122       
00123       //@}
00124       
00125       //! \name Point Comparison Functions
00126       //@{
00127    
00128       //! \brief Is the distance squared between the two points essentially zero?
00129       bool is_equal(const P& p, double epsSqrd = epsAbsSqrdMath()) const
00130          { return dist_sqrd(p) <= epsSqrd; }
00131       
00132       //@}
00133 
00134 };
00135 
00136 } // namespace mlib
00137 
00138 /* ---------- inlined global functions using Point3 template ------ */
00139 
00140 namespace mlib {
00141 
00142 //! \brief Stream insertion operator for Point3's.
00143 //! \relates Point3
00144 template <typename P, typename V>
00145 inline ostream& 
00146 operator<<(ostream& os, const Point3<P,V>& p) 
00147 { 
00148    return os << "< " << p[0] << " " << p[1] << " " << p[2] << " > ";
00149 }
00150 
00151 //! \brief Stream extraction operator for Point3's.
00152 //! \relates Point3
00153 template <typename P, typename V>
00154 inline istream& 
00155 operator>>(istream& is, Point3<P,V>& p) 
00156 { 
00157    char dummy;
00158    return is >> dummy >> p[0] >> p[1] >> p[2] >> dummy;
00159 }
00160 
00161 //! \brief Computes the determinant of the 3x3 matrix containing the 3 Point3's
00162 //! as rows.
00163 //! \relates Point3
00164 template <typename P, typename V>
00165 inline double 
00166 det(const Point3<P,V>& a, const Point3<P,V>& b, const Point3<P,V>& c)
00167 {
00168    return (a[0] * (b[1]*c[2] - b[2]*c[1]) +
00169            a[1] * (b[2]*c[0] - b[0]*c[2]) +
00170            a[2] * (b[0]*c[1] - b[1]*c[0]));
00171 } 
00172 
00173 //! \brief Determines if four Point3's are co-planar.
00174 //! \relates Point3
00175 template <typename P>
00176 extern bool areCoplanar(const P&, const P&, const P&, const P&);
00177 
00178 } // namespace mlib
00179 
00180 namespace mlib {
00181 
00182 /*!
00183  *  \brief A class containing a list of Point3's.  Contains functions to aid in
00184  *  using this list of points as a piecewise continuous curve in some 3D
00185  *  coordinate system.
00186  *  \ingroup group_MLIB
00187  *
00188  *  Like the Point3 class, Point3list is designed to be the base class for more
00189  *  specific types of lists of 3D points.  Specifically, lists of 3D points in
00190  *  different coordinate systems.  The template argument L is the type of the
00191  *  derived point list class.  This allows the Point3list to return new lists of
00192  *  the same type as the derived class.  The template arguments M, P, V, and S
00193  *  are the types of the corresponding matrix, point, vector and line classes
00194  *  (respectively) for the coordinate system of the derived 3D point list class.
00195  *
00196  */
00197 template <typename L, typename M, typename P, typename V, typename S>
00198 class Point3list : public Pointlist<L,P,V,S> {
00199 
00200    public:
00201 
00202       //! \name Constructors
00203       //@{
00204 
00205       //! \brief Default constructor.  Creates an empty list with space for max
00206       //! points.
00207       Point3list(int max=16) : Pointlist<L,P,V,S>(max) { }
00208       
00209       //! \brief Constructor that creates a list containing the points in ARRAY
00210       //! p.
00211       Point3list(const ARRAY<P>& p) : Pointlist<L,P,V,S>(p) { }
00212       
00213       //! \brief Constructor that creates a list containing the points in ARRAY
00214       //! p transformed by matrix t.
00215       Point3list(const ARRAY<P>& p, const M& t) : Pointlist<L,P,V,S>(p) {
00216          xform(t);
00217       }
00218       
00219       //@}
00220 
00221       //! \name Point List Property Queries
00222       //@{
00223 
00224       //! \brief Returns the winding number WRT the given point and direction.
00225       //! 
00226       //! I.e., projects the polyline to the plane containing point 'o'
00227       //! and perpendicular to direction 'n', then computes the number of
00228       //! times the result winds around o in the CCW direction. For a
00229       //! closed polyline the result is an integer: e.g. +1 if it winds
00230       //! around once CCW, -1 if it winds once clockwise, and 0 if o is
00231       //! outside the projected polyline.
00232       double winding_number(const P& o, const V& n) const;
00233       
00234       //@}
00235    
00236       //! \name List Operations
00237       //@{
00238    
00239       //! \brief Multiply the points by the transform
00240       void xform(const M& t);
00241    
00242       //! \brief Adjust this polyline so that it runs from a to b
00243       //! (uses a combination of translation, rotation, and scaling).
00244       //!
00245       //! Pass input parameters by copying in case one is a current
00246       //! endpoint of the polyline
00247       bool fix_endpoints(P a, P b);
00248       
00249       //@}
00250 
00251       using Pointlist<L,P,V,S>::num;
00252       using Pointlist<L,P,V,S>::last;
00253       using Pointlist<L,P,V,S>::pt;
00254       using Pointlist<L,P,V,S>::update_length;
00255    
00256 };
00257 
00258 } // namespace mlib
00259 
00260 #ifdef JOT_NEEDS_TEMPLATES_IN_H_FILE
00261 #include "point3.C"
00262 #endif
00263 
00264 #endif // POINT3_H_IS_INCLUDED
00265 
00266 /* end of file Point3.H */

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