2 #ifndef vgl_polygon_scan_iterator_hxx_ 3 #define vgl_polygon_scan_iterator_hxx_ 13 # include <vcl_msvc_warnings.h> 35 static const float vgl_polygon_scan_iterator_offset = 0.0f;
39 #define MIN(a,b) (((a)<(b))?(a):(b)) 43 #define MAX(a,b) (((a)>(b))?(a):(b)) 128 for (
unsigned int s = 0; s < poly_.num_sheets(); ++s)
129 numverts +=
int(poly_[s].size());
131 unsigned int numchains = poly_.num_sheets();
133 if ( numverts == 0 ) {
137 crossedges =
nullptr;
146 yverts =
new vertind[ numverts ];
148 for (
unsigned int j = 0; j < numchains; j++ )
149 for (
unsigned int h = 0; h < poly_[ j ].size(); h++ )
156 std::cout <<
"Error: i does not equal numverts!\n";
159 local_qsort<T>(yverts, numverts, poly_);
162 miny = get_y( yverts[ 0 ] );
163 maxy = get_y( yverts[ numverts - 1 ] );
169 y0 = (int)
MAX(win.min_y(), std::floor( miny - vgl_polygon_scan_iterator_offset));
171 y0 = (int)
MAX(win.min_y(), std::ceil( miny - vgl_polygon_scan_iterator_offset));
174 y1 = (int)
MIN(win.max_y()-1, std::ceil( maxy - vgl_polygon_scan_iterator_offset));
176 y1 = (int)
MIN(win.max_y()-1, std::floor( maxy - vgl_polygon_scan_iterator_offset));
181 y0 = (int)std::floor( miny - vgl_polygon_scan_iterator_offset);
183 y0 = (int)std::ceil( miny - vgl_polygon_scan_iterator_offset);
186 y1 = (int)std::ceil( maxy - vgl_polygon_scan_iterator_offset);
188 y1 = (int)std::floor( maxy - vgl_polygon_scan_iterator_offset);
199 for ( j = 0; j < numcrossedges &&
201 crossedges[j].
v.
vertnum ==
v.vertnum ); ++j )
205 if ( j >= numcrossedges )
return;
208 std::memmove(&crossedges[j], &crossedges[j+1],
209 (numcrossedges-j)*
sizeof( crossedges[0] ));
222 get_next_vert(
v, nextvert );
223 if ( get_y(
v ) < get_y( nextvert ) )
226 q = get_pt( nextvert );
230 p = get_pt( nextvert );
235 crossedges[numcrossedges].
dx = dx = (q.
x() - p.
x()) / (q.
y() - p.
y());
236 crossedges[numcrossedges].
x = dx * ( fy + vgl_polygon_scan_iterator_offset - p.
y() ) + p.
x();
237 crossedges[numcrossedges].
v =
v;
262 static inline int irnd(T x)
264 return (
int)std::floor(x + 0.5);
270 num_crossedges=numcrossedges;
272 chainnum=
new int[num_crossedges];
273 vertnum=
new int[num_crossedges];
274 while ( current < numcrossedges )
276 chainnum[current] = crossedges[current].
v.
chainnum;
277 vertnum[current] = crossedges[current].
v.
vertnum;
293 while ( curcrossedge < numcrossedges )
295 fxl = crossedges[curcrossedge].
x;
296 fxr = crossedges[curcrossedge+1].
x;
299 xl = (int)std::floor( crossedges[curcrossedge].x - vgl_polygon_scan_iterator_offset);
302 xl = (int)std::ceil( crossedges[curcrossedge].x - vgl_polygon_scan_iterator_offset);
304 if ( have_window && xl < irnd(win.min_x()) )
312 xr = (int)std::ceil( crossedges[curcrossedge+1].x - vgl_polygon_scan_iterator_offset);
315 xr = (int)std::floor( crossedges[curcrossedge+1].x - vgl_polygon_scan_iterator_offset);
317 if ( have_window && xr >= irnd(win.max_x()) )
319 fxr = win.max_x() -1;
322 #if 0 // TODO: added by Vishal Jain (Brown U) but breaks the tests - please fix! 323 if (xr==crossedges[curcrossedge+1].x)
328 crossedges[curcrossedge].
x += crossedges[curcrossedge].
dx;
329 crossedges[curcrossedge+1].
x += crossedges[curcrossedge+1].
dx;
337 vertind curvert, prevvert, nextvert;
343 bool not_last =
true;
351 fy = std::floor(get_y( yverts[ 0 ] ));
352 else if ( y == y1 ) {
353 fy = std::ceil(get_y( yverts[ numverts - 1 ] ));
362 for (; k<numverts && get_y(yverts[k]) <= fy+vgl_polygon_scan_iterator_offset && not_last; k++)
364 curvert = yverts[ k ];
368 get_prev_vert( curvert, prevvert );
370 if ( get_y( prevvert ) <= fy-vgl_polygon_scan_iterator_offset)
371 delete_edge( prevvert );
372 else if ( get_y( prevvert ) > fy+vgl_polygon_scan_iterator_offset)
373 insert_edge( prevvert );
375 get_next_vert( curvert, nextvert );
377 if ( get_y( nextvert ) <= fy-vgl_polygon_scan_iterator_offset)
378 delete_edge( curvert );
379 else if ( get_y( nextvert ) > fy+vgl_polygon_scan_iterator_offset)
380 insert_edge( curvert );
384 local_qsort<T>(crossedges, numcrossedges);
425 std::cout <<
"Number of Chains: " << poly_.num_sheets() << std::endl
426 <<
"Number of Vertices: " << numverts << std::endl;
427 for (
unsigned int c = 0; c < poly_.num_sheets(); ++c )
429 std::cout <<
"---- Chain # " << c <<
" ----\n" 430 <<
" Length: " << poly_[ c ].size() << std::endl;
431 for (
unsigned int v = 0;
v < poly_[ c ].size();
v++ )
433 std::cout <<
" [ " << poly_[ c ][
v ].x()
434 <<
' ' << poly_[ c ][
v ].y() <<
" ]\n";
437 std::cout << std::flush;
446 std::cout <<
"----- CROSSEDGES -----\n" 447 <<
"numcrossedges: " << numcrossedges << std::endl;
448 for (
int i = 0; i< numcrossedges; i++ )
450 std::cout <<
"x = " << crossedges[i].
x <<
'\n' 451 <<
"y = " << crossedges[i].
dx <<
'\n' 452 <<
"v: chainnum=" << crossedges[i].
v.
chainnum 453 <<
", vertnum=" << crossedges[i].
v.
vertnum <<
'\n';
455 std::cout <<
"---------------------\n" << std::flush;
458 #undef VGL_POLYGON_SCAN_ITERATOR_INSTANTIATE 459 #define VGL_POLYGON_SCAN_ITERATOR_INSTANTIATE(T) \ 460 template class vgl_polygon_scan_iterator<T > 462 #endif // vgl_polygon_scan_iterator_hxx_ 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.
bool next() override
Moves iterator to next segment.
~vgl_polygon_scan_iterator() override
Destructor.
int chainnum
which chain the vertex is part of
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.
compare_vertind(typename vgl_polygon< T >::sheet_t *chs)
vertind v
edge goes from vertex v.vertnum to v.vertnum + 1
void insert_edge(vertind v)
bool operator()(const typename vgl_polygon_scan_iterator< T >::vertind &u, const typename vgl_polygon_scan_iterator< T >::vertind &v) const
void get_crossedge_vertices(int *&chainnum, int *&vertnum, int &numcrossedges)
vgl_polygon_scan_iterator(vgl_polygon< T > const &face, bool boundaryp=true)
Construct with a polygon and bool indicating whether boundary included.
void display_crossedges()
T dx
change in x with respect to y
Vertex index - uniquely identifies a vertex in the array chains.
int vertnum
which vertex in the chain
void delete_edge(vertind v)
void reset() override
Resets iterator to first segment of first scan line.
T x
x coord of edge's intersection with current scanline
bool operator()(const typename vgl_polygon_scan_iterator< T >::crossedge &u, const typename vgl_polygon_scan_iterator< T >::crossedge &v) const
std::vector< point_t > sheet_t
vgl_polygon< T >::sheet_t * chs_
vgl_box_2d< T > win
clipping window