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

pointlist.H

Go to the documentation of this file.
00001 #ifndef POINTLIST_H_IS_INCLUDED
00002 #define POINTLIST_H_IS_INCLUDED
00003 
00004 /*!
00005  *  \file Pointlist.H
00006  *  \brief Contains the declaration of the Pointlist class.
00007  *  \ingroup group_MLIB
00008  *
00009  */
00010 
00011 #include "std/support.H"
00012 
00013 namespace mlib {
00014 
00015 /*!
00016  *  \brief A class containing a list of points.  Contains functions to aid in
00017  *  using this list of points as a piecewise continuous curve in some coordinate
00018  *  system.
00019  *  \ingroup group_MLIB
00020  *
00021  *  Pointlist is designed to be the base class for more specific types of lists
00022  *  of points.  Specifically, lists of points with different numbers of
00023  *  dimensions.  The template argument L is the type of the derived point list
00024  *  class.  This allows the Pointlist to return new lists of the same type as
00025  *  the derived class.  The template arguments P, V, and S are the types of the
00026  *  corresponding point, vector and line classes (respectively) for the derived
00027  *  class.
00028  *
00029  */
00030 template <class L,class P,class V,class S>
00031 class Pointlist : public ARRAY<P> {
00032    
00033    protected:
00034    
00035       ARRAY<double>    _partial_length;
00036 
00037    public:
00038    
00039       //! \name Constructors
00040       //@{
00041  
00042       //! \brief Construct a list with no points but space for m points.
00043       Pointlist(int m=16) : ARRAY<P>(m), _partial_length(0) { }
00044       
00045       //! \brief Construct a list using the passed in array of points.
00046       Pointlist(const ARRAY<P> &p) : ARRAY<P>(p), _partial_length(0) {
00047          update_length();
00048       }
00049       
00050       //@}
00051       
00052       //! \name Point, Vector and Segment Accessors
00053       //@{
00054          
00055       //! \brief Get the i<sup>th</sup> point in the list.
00056       P pt(int i)  const { return (*this)[i]; }
00057       //! \brief Get the vector from the i<sup>th</sup> point in the list to the
00058       //! (i + 1)<sup>th</sup> point in the list.
00059       V vec(int i) const { return (*this)[i+1]-(*this)[i];}
00060    
00061       //! \brief Get the length of the i<sup>th</sup> segment in the list.
00062       double segment_length(int i) const { return vec(i).length(); }
00063    
00064       //! \brief Get the i<sup>th</sup> segment in the list.
00065       S seg(int i) const { return S(pt(i), pt(i+1)); }
00066       
00067       //! \brief Returns a "tangent" direction at each vertex.
00068       //! 
00069       //! At the endpoints it is the direction of the ending
00070       //! segment.  At internal vertices it is the average of
00071       //! the two segment directions.
00072       V tan(int i) const {
00073          const int n = num()-1;
00074          if (i<0 || i>n || n<1)
00075             return V::null();
00076          if (i==0) return (vec(0))  .normalized();
00077          if (i==n) return (vec(n-1)).normalized();
00078          return (vec(i).normalized() + vec(i-1).normalized()).normalized();
00079       }
00080       
00081       //@}
00082       
00083       //! \name Point List Property Queries
00084       //@{
00085       
00086       //! \brief It's considered a closed loop if the first and last point
00087       //! are the same.
00088       bool is_closed() const {
00089          return (num() > 2 && ((*this)[0] == last()));
00090       }
00091       
00092       //! \brief Returns true if the points fall in a straight line.
00093       //! 
00094       //! len_scale * length() gives the threshold for how close
00095       //! points have to be to the proposed straight line to be
00096       //! accepted.
00097       bool is_straight(double len_scale=1e-5) const;
00098       
00099       //! \brief Does O(n^2) check to see if any segment of the
00100       //! polyline intersects any other, not counting adjacent
00101       //! segments of course.
00102       bool self_intersects() const;
00103       
00104       //@}
00105       
00106       //! \name Near Point Functions
00107       //! Functions for finding the nearest point in a point list to another
00108       //! point.
00109       //@{
00110       
00111       //! \brief Finds the index of the nearest point in the point list to point p.
00112       int     nearest_point   (const P &p)                          const;
00113       
00114       //! \brief Computes everything about the point on the line closest to p.
00115       void    closest (const P &p, P &, double &, int &)            const;
00116       
00117       double  closest (const P &p, P &, int &)                      const;
00118       
00119       P       closest (const P &p)                                  const;
00120       
00121       //@}
00122       
00123       //! \name Geometric Computations
00124       //@{
00125          
00126       //! \brief Computes the sum of all the points in the list.
00127       P sum() const;
00128       
00129       //! \brief Computes the average of all the point sin the list.
00130       P average () const { return empty() ? P::Origin() : sum()/num(); }
00131       
00132       //! \brief Computes the distance from point p to the nearest point on
00133       //! segment k in the list.
00134       double  dist_to_seg     (const P &p, int k)                   const;
00135       
00136       //! \brief Computes the averge distance from point p to segment k in the
00137       //! list over the length of segment k.
00138       double  avg_dist_to_seg (const P &p, int k)                   const;
00139       
00140       //! \brief Distance of the point to the nearest point on the polyline.
00141       double dist(const P& p) const { return closest(p).dist(p); }
00142       
00143       //! \brief Max distance of any point to average().
00144       double  spread() const;
00145       
00146       //! \brief Returns the min value, over the polyline, for the given
00147       //! component i.
00148       typename P::value_type min_val(int i) const;
00149    
00150       //! \brief Returns the max value, over the polyline, for the given
00151       //! component i.
00152       typename P::value_type max_val(int i) const;
00153       
00154       //@}
00155       
00156       //! \name Length Functions
00157       //@{
00158       
00159       //! This must be called before the interpolation routines
00160       //! can work properly.
00161       void    update_length();
00162       
00163       //! \brief Net length along the polyline at vertex i.
00164       double  partial_length(int i) const {
00165          return _partial_length.valid_index(i) ? _partial_length[i] : 0;
00166       }
00167       
00168       double  length() const { return _partial_length.last(); }
00169       
00170       double avg_len() const
00171          { return (num() > 1) ? length()/(num()-1) : 0; }
00172       
00173       //@}
00174        
00175       //! \name Interpolation Functions
00176       //@{
00177       
00178       //! \brief Computes interpolated values over the polyline.
00179       P interpolate(double s, V *tan=0, int *segp=0, double *tp=0) const;
00180       
00181       
00182       //! \brief Finds the segment containing the interpolation paramenter \p s
00183       //! and the position of \p s within that segment (as a parameter between
00184       //! 0 and 1).
00185       void interpolate_length(double s, int &seg, double &t) const;
00186       
00187       //! \brief Computes the interpolated tangent at \p s on the polyline.
00188       V get_tangent(double s) const;
00189       
00190       //@}
00191       
00192       //! \name Inversion Functions
00193       //@{
00194       
00195       double  invert             (const P &p)                     const;
00196       double  invert             (const P &p, int seg)            const;
00197       
00198       //@}
00199       
00200       //! \name List Operations
00201       //@{
00202          
00203       //! \brief Translate all points in polyline by given vector.
00204       //! \param[in] vec Vector that represents translation to be applied.
00205       void  translate   (const V& vec) {
00206          for (int i = 0; i < num(); i++) (*this)[i] = (*this)[i] + vec;
00207       }
00208       
00209       //! \brief Resample with the desired number of segments:
00210       void resample(int num_segs);
00211       
00212       //@}
00213             
00214       //! \name List Editing Functions
00215       //@{
00216       
00217       //! \brief Make a copy of the point list from point \p k1 to point \p k2.
00218       L  clone_piece(int k1, int k2) const;
00219       
00220       //! \brief Appends all the points in \p poly onto the list.
00221       void    append          (Pointlist<L,P,V,S> *poly);
00222       //! \brief Prepends all the points in \p poly onto the list.
00223       void    prepend         (Pointlist<L,P,V,S> *poly);
00224       
00225       //@}
00226       
00227       //! \name Overriden ARRAY Class Virtual Methods
00228       //@{
00229          
00230       virtual void clear() {
00231          ARRAY<P>::clear();
00232          _partial_length.clear();
00233       }
00234          
00235       virtual void shift(int p) {
00236          ARRAY<P>::shift(p);
00237          update_length();
00238       }
00239       
00240       //@}
00241 
00242       using ARRAY<P>::num;
00243       using ARRAY<P>::empty;
00244       using ARRAY<P>::last;
00245       using ARRAY<P>::valid_index;
00246 
00247 };
00248 
00249 } // namespace mlib
00250 
00251 #ifdef JOT_NEEDS_TEMPLATES_IN_H_FILE
00252 #include "pointlist.C"
00253 #endif
00254 
00255 #endif // POINTLIST_H_IS_INCLUDED

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