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_