vgl_polygon_scan_iterator.h
Go to the documentation of this file.
1 // This is core/vgl/vgl_polygon_scan_iterator.h
2 #ifndef vgl_polygon_scan_iterator_h
3 #define vgl_polygon_scan_iterator_h
4 //:
5 // \file
6 // \author Adapted from FillPolygon by J.L. Mundy
7 //
8 // \verbatim
9 // Modifications
10 // Binary IO added and documentation tidied up NPC, 20/03/01
11 // Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line
12 // Nov.2003 - Peter Vanroose - made vgl_polygon_scan_iterator a templated class
13 // Apr.2004 - Peter Vanroose - corrected an earlier with_boundary fix in next()
14 // \endverbatim
15 
17 #include <vgl/vgl_polygon.h>
18 #include <vgl/vgl_box_2d.h>
19 
20 //: Fill a polygonal face with interior scan lines
21 // This class provides an iterator-style interface to polygon scan
22 // conversion. There are convenient constructors from vgl_polygon, and_
23 // lists of floats. An auxiliary clipping window can be specified by the
24 // constructor argument, vgl_box_2d<T> win.
25 //
26 // Concave Polygon Scan Conversion
27 // by Paul Heckbert
28 // from "Graphics Gems", Academic Press, 1990
29 //
30 // Scan convert nvert-sided concave non-simple polygon
31 // with vertices at (point[i].x, point[i].y)
32 // for i in [0..nvert-1] within the window win by
33 // calling spanproc for each visible span of pixels.
34 // Polygon can be clockwise or counterclockwise.
35 // Algorithm does uniform point sampling at pixel centers.
36 // Inside-outside test done by Jordan's rule: a point is considered inside if
37 // an emanating ray intersects the polygon an odd number of times.
38 //
39 // Note: The span limits, startx and endx, are closed intervals.
40 // That is, you can use the endpoints of the span as valid interior points.
41 // Also, the initial and final y scan lines returned by the iterator
42 // are interior to the polygon. The constructor argument, win, is a clipping
43 // window that is intersected with the polygonal region to determine the actual
44 // scanned area.
45 //
46 // Example usage:
47 // \code
48 // vgl_polygon_scan_iterator<float> psi(mypoints);
49 // psi.set_include_boundary(true); // optional flag, default is true
50 // for (psi.reset(); psi.next(); ) {
51 // int y = psi.scany();
52 // for (int x = psi.startx(); x <= psi.endx(); ++x)
53 // ....
54 // }
55 // \endcode
56 template <class T>
58 {
59  int boundp; //!< boolean indicating if boundary should be included or not
60  int xl; //!< left bound of current span
61  T fxl; //!< left bound of current span (floating point value)
62  int xr; //!< right bound of current span
63  T fxr; //!< right bound of current span (floating point value)
64  int k; //!< current index of vertices ordered by increasing y
65  int y0; //!< bottommost scan line
66  int y1; //!< topmost scan line
67  int y; //!< current scan line
68  T fy; //!< floating point value of current scan line (i.e. T(y))
69  int curcrossedge; //!< crossedge marking start of next scan segment
70  vgl_box_2d<T> win;//!< clipping window
72 
73  vgl_polygon<T> poly_; //!< the polygon
74 
75  public:
76  // Stores coordinates of a 2d point
77  typedef typename vgl_polygon<T>::point_t Point2;
78 
79  // Constructors/Destructor---------------------------------------------------
80 
81  //: Construct with a polygon and bool indicating whether boundary included
82  vgl_polygon_scan_iterator(vgl_polygon<T> const& face, bool boundaryp = true);
83 
84  //: Construct with a polygon, bool indicating whether boundary included and window (area visible)
85  vgl_polygon_scan_iterator(vgl_polygon<T> const& face, bool boundaryp,
86  vgl_box_2d<T> const& window);
87 
88  //: Destructor
89  ~vgl_polygon_scan_iterator() override;
90 
91  //Functions----------------------------------------------------------
92 
93  //: Resets iterator to first segment of first scan line
94  void reset() override;
95 
96  //: Moves iterator to next segment
97  bool next() override;
98 
99  //: Returns current scan line
100  inline int scany() const override { return y-1; }
101 
102  //: Returns start of current span
103  inline int startx() const override { return xl; }
104 
105  //: Returns end of current span
106  inline int endx() const override { return xr; }
107 
108  //: Returns start of current span (floating point value)
109  inline T fstartx() const { return fxl; }
110 
111  //: Returns end of current span (floating point value)
112  inline T fendx() const { return fxr; }
113 
114  //: Returns current scan line (floating point value)
115  inline T fscany() const { return fy; }
116 
117  // returns the vertices related to
118  void get_crossedge_vertices(int * &chainnum, int * &vertnum, int & numcrossedges);
119  //: Vertex index - uniquely identifies a vertex in the array chains
120  struct vertind {
121  int chainnum; //!< which chain the vertex is part of
122  int vertnum; //!< which vertex in the chain
123  };
124 
125  //: Describes an edge crossing the current scan line
126  struct crossedge {
127  T x; //!< x coord of edge's intersection with current scanline
128  T dx; //!< change in x with respect to y
129  vertind v; //!< edge goes from vertex v.vertnum to v.vertnum + 1
130  };
131 
132 // Internals ---------------------------------------------------------------
133 
134  private:
135  // avoid copy constructor a operator=
138 
139  vertind * yverts; //!< array of all vertices ordered by y coordinate
140  crossedge * crossedges; //!< array of edges crossing current scan line
141  int numcrossedges; //!< number of edges currently crossing scan line
142  int numverts; //!< total number of vertices comprising face
143 
144  // Returns x coord of vertex v
145  inline T get_x(vertind v) const { return poly_[v.chainnum][v.vertnum].x(); }
146 
147  // Returns y coord of vertex v
148  inline T get_y(vertind v) const { return poly_[v.chainnum][v.vertnum].y(); }
149 
150  // Returns vertex v
151  inline Point2 get_pt( vertind v ) const { return poly_[v.chainnum][v.vertnum]; }
152 
153  // assumes poly_, win, have_window, boundp are set
154  void init();
155 
156  // Deletes edge (v,get_next_vert(v)) from crossedges array
157  void delete_edge( vertind v );
158 
159  // Inserts edge (v,get_next_vert(v)) into crossedges array
160  void insert_edge( vertind v );
161 
162  // Returns next vertex on chain
163  void get_next_vert( vertind v, vertind & next );
164 
165  // Returns prev vertex on chain
166  void get_prev_vert( vertind v, vertind & prev );
167 
168  // For debugging purposes
169  void display_chains();
170  void display_crossedges();
171 };
172 
173 #define VGL_POLYGON_SCAN_ITERATOR_INSTANTIATE(T) extern "please include <vgl/vgl_polygon_scan_iterator.hxx> instead"
174 
175 #endif // vgl_polygon_scan_iterator_h
int xr
right bound of current span
int boundp
boolean indicating if boundary should be included or not
void get_next_vert(vertind v, vertind &next)
Returns the vertex following v in v's chain.
int curcrossedge
crossedge marking start of next scan segment
T fscany() const
Returns current scan line (floating point value).
T fstartx() const
Returns start of current span (floating point value).
bool next() override
Moves iterator to next segment.
~vgl_polygon_scan_iterator() override
Destructor.
T fy
floating point value of current scan line (i.e. T(y))
int chainnum
which chain the vertex is part of
int numcrossedges
number of edges currently crossing scan line
Describes an edge crossing the current scan line.
void get_prev_vert(vertind v, vertind &prev)
Returns the vertex preceding v in v's chain.
int xl
left bound of current span
int startx() const override
Returns start of current span.
#define v
Definition: vgl_vector_2d.h:74
vertind v
edge goes from vertex v.vertnum to v.vertnum + 1
Fill a polygonal face with interior scan lines.
Definition: vgl_fwd.h:33
vgl_polygon< T >::point_t Point2
crossedge * crossedges
array of edges crossing current scan line
void get_crossedge_vertices(int *&chainnum, int *&vertnum, int &numcrossedges)
T fendx() const
Returns end of current span (floating point value).
vgl_polygon_scan_iterator & operator=(const vgl_polygon_scan_iterator &)=delete
int endx() const override
Returns end of current span.
vgl_polygon_scan_iterator(vgl_polygon< T > const &face, bool boundaryp=true)
Construct with a polygon and bool indicating whether boundary included.
vertind * yverts
array of all vertices ordered by y coordinate
Contains class to represent a cartesian 2D bounding box.
int k
current index of vertices ordered by increasing y
vgl_polygon< T > poly_
the polygon
Vertex index - uniquely identifies a vertex in the array chains.
Abstract base class for iterating over the pixels in a region of an image.
T fxr
right bound of current span (floating point value)
int numverts
total number of vertices comprising face
void reset() override
Resets iterator to first segment of first scan line.
T x
x coord of edge's intersection with current scanline
Store a polygon.
Definition: vgl_area.h:6
T fxl
left bound of current span (floating point value)
vgl_box_2d< T > win
clipping window
int scany() const override
Returns current scan line.