core/vgl/vgl_polygon.h
Go to the documentation of this file.
00001 // This is core/vgl/vgl_polygon.h
00002 #ifndef vgl_polygon_h_
00003 #define vgl_polygon_h_
00004 //:
00005 // \file
00006 // \author awf@robots.ox.ac.uk
00007 // \date   02 Apr 2000
00008 //
00009 // \verbatim
00010 //  Modifications
00011 //   Binary IO added and documentation tidied up NPC, 20/03/01
00012 //   Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line
00013 //   Nov.2003 - Peter Vanroose - made vgl_polygon a templated class and added lost of documentation
00014 //   Nov.2003 - Peter Vanroose - added constructor (to replace new_polygon from test_driver)
00015 //   May.2009 - Matt Leotta - added a function to find self-intersections
00016 // \endverbatim
00017 
00018 #include <vcl_iosfwd.h>
00019 #include <vgl/vgl_point_2d.h> // needed for vcl_vector instantiations
00020 #include <vcl_vector.h>
00021 #include <vcl_utility.h> // for vcl_pair
00022 
00023 //: Store a polygon.
00024 // May have holes or multiple sections.  The polygon is stored as a list
00025 // of "sheets", each sheet is a list of 2d points.
00026 // Iterate through all points using
00027 //
00028 // for (unsigned int s = 0; s < polygon.num_sheets(); ++s)
00029 //   for (unsigned int p = 0; p < polygon[s].size(); ++p)
00030 //     do_something(polygon[s][p].x(), polygon[s][p].y());
00031 //
00032 template <class T>
00033 class vgl_polygon
00034 {
00035  public:
00036   typedef vgl_point_2d<T> point_t;
00037 
00038   typedef vcl_vector<point_t> sheet_t;
00039 
00040   // Constructors/Destructor---------------------------------------------------
00041 
00042   //: Default constructor - constructs an empty polygon with no sheets
00043   vgl_polygon() {}
00044 
00045   //: Construct an empty polygon, setting the number of (empty) sheets
00046   explicit vgl_polygon(unsigned int nr_sheets) : sheets_(nr_sheets) {}
00047 
00048   //: Construct a single-sheet polygon from a list of n points.
00049   //  More sheets can be added later with the add_contour method.
00050   vgl_polygon(point_t const p[], int n);
00051 
00052   //: Construct a single-sheet polygon from a list of n points.
00053   //  More sheets can be added later with the add_contour method.
00054   vgl_polygon(T const* x, T const* y, int n);
00055 
00056   //: Construct a single-sheet polygon from a list of n points, given in (x,y) pairs.
00057   //  The x_y array should thus be of size 2*n !
00058   //  More sheets can be added later with the add_contour method.
00059   vgl_polygon(T const x_y[], int n);
00060 
00061   //: Construct a single-sheet polygon from a sheet, i.e., a vector of 2D points.
00062   //  Note: n_sheets is only there to distinguish this from the next constructor for VC6
00063   //  which seems to have a problem.
00064   explicit vgl_polygon(sheet_t const& points, unsigned n_sheets=1) : sheets_(n_sheets,points) {}
00065 
00066   //: Construct by specifying all of its sheets
00067   explicit vgl_polygon(vcl_vector<sheet_t> const& sheets) : sheets_(sheets) {}
00068 
00069   // Copy constructor
00070   vgl_polygon(vgl_polygon const& a) : sheets_(a.sheets_) {}
00071 
00072   // Destructor
00073   ~vgl_polygon() {}
00074 
00075   //: Returns true if \a p(x,y) is inside the polygon, else false
00076   bool contains(point_t const& p) const { return contains(p.x(),p.y()); }
00077 
00078   bool contains(T x, T y) const;
00079 
00080   // creation
00081 
00082   //: Add a single sheet to this polygon, specified by the given list of n points.
00083   // This increments the number of sheets by one.
00084   void add_contour(point_t const p[], int n);
00085 
00086   //: Add a single sheet to this polygon, specified by the given list of n points.
00087   // This increments the number of sheets by one.
00088   void add_contour(T const* x, T const* y, int n);
00089 
00090   //: Add a single sheet to this polygon, specified by the given list of n (x,y) pairs.
00091   //  The x_y array should thus be of size 2*n !
00092   // This increments the number of sheets by one.
00093   void add_contour(T const x_y[], int n);
00094 
00095   //: Set the number of sheets to zero, so the polygon becomes empty
00096   void clear() { sheets_.resize(0); }
00097 
00098   //: Add a new (empty) sheet to the polygon.
00099   // This increments the number of sheets by one.
00100   void new_sheet() { sheets_.push_back(sheet_t()); }
00101 
00102   //: Add a new point to the last sheet
00103   void push_back(T x, T y);
00104 
00105   //: Add a new point to the last sheet
00106   void push_back(point_t const&);
00107 
00108   //: Add a pre-existing sheet to the polygon
00109   void push_back(sheet_t const& s) { sheets_.push_back(s); }
00110 
00111   inline unsigned int num_sheets() const { return (unsigned int)(sheets_.size()); }
00112 
00113   inline unsigned int num_vertices() const {
00114     unsigned int c=0;
00115     for (unsigned int i=0;i<num_sheets();++i) c += (unsigned int)(sheets_[i].size());
00116     return c;
00117   }
00118 
00119   //: Get the ith sheet
00120   inline sheet_t& operator[](int i) { return sheets_[i]; }
00121 
00122   //: Get the ith sheet
00123   inline sheet_t const& operator[](int i) const { return sheets_[i]; }
00124 
00125   //: Pretty print
00126   vcl_ostream& print(vcl_ostream&) const;
00127 
00128  protected:
00129 
00130   // Data Members--------------------------------------------------------------
00131   vcl_vector<sheet_t> sheets_;
00132 };
00133 
00134 //: A commonly required (single-sheet) polygon representation.
00135 template <class T>
00136 struct vgl_polygon_sheet_as_array
00137 {
00138   int n;
00139   T* x;
00140   T* y;
00141 
00142   //: Automatic constructor from a single-sheet polygon
00143   vgl_polygon_sheet_as_array(vgl_polygon<T> const& p);
00144 
00145   //: Automatic constructor from a polygon sheet
00146   vgl_polygon_sheet_as_array(typename vgl_polygon<T>::sheet_t const& p);
00147 
00148   //: Destructor
00149   ~vgl_polygon_sheet_as_array();
00150 };
00151 
00152 //: Compute all self-intersections between all edges on all sheets.
00153 // \returns three arrays \a e1, \a e2, and \a ip of equal size.
00154 // Corresponding elements from these arrays describe an intersection.
00155 // e1[k].first is the sheet index containing edge (e1[k].second, e1[k].second+1)
00156 // involved in the k-th intersection.  Similarly, e2[k] indexes the other
00157 // edge involved in the k-th intersection.  The corresponding intersection
00158 // point is returned in ip[k].
00159 template <class T>
00160 void vgl_selfintersections(vgl_polygon<T> const& p,
00161                            vcl_vector<vcl_pair<unsigned,unsigned> >& e1,
00162                            vcl_vector<vcl_pair<unsigned,unsigned> >& e2,
00163                            vcl_vector<vgl_point_2d<T> >& ip);
00164 
00165 // \relatesalso vgl_polygon
00166 template <class T>
00167 vcl_ostream& operator<< (vcl_ostream& os, vgl_polygon<T> const& p) { return p.print(os); }
00168 
00169 #define VGL_POLYGON_INSTANTIATE(T) extern "please include vgl/vgl_polygon.txx instead"
00170 
00171 #endif // vgl_polygon_h_