inT16 POLY_BLOCK::winding_number(const ICOORD &point) { inT16 count; //winding count ICOORD pt; //current point ICOORD vec; //point to current point ICOORD vvec; //current point to next point inT32 cross; //cross product ICOORDELT_IT it = &vertices; //iterator count = 0; do { pt = *it.data (); vec = pt - point; vvec = *it.data_relative (1) - pt; //crossing the line if (vec.y () <= 0 && vec.y () + vvec.y () > 0) { cross = vec * vvec; //cross product if (cross > 0) count++; //crossing right half else if (cross == 0) return INTERSECTING; //going through point } else if (vec.y () > 0 && vec.y () + vvec.y () <= 0) { cross = vec * vvec; if (cross < 0) count--; //crossing back else if (cross == 0) return INTERSECTING; //illegal } else if (vec.y () == 0 && vec.x () == 0) return INTERSECTING; it.forward (); } while (!it.at_first ()); return count; //winding number }
void POLY_BLOCK::compute_bb() { //constructor ICOORD ibl, itr; //integer bb ICOORD botleft; //bounding box ICOORD topright; ICOORD pos; //current pos; ICOORDELT_IT pts = &vertices; //iterator botleft = *pts.data (); topright = botleft; do { pos = *pts.data (); if (pos.x () < botleft.x ()) //get bounding box botleft = ICOORD (pos.x (), botleft.y ()); if (pos.y () < botleft.y ()) botleft = ICOORD (botleft.x (), pos.y ()); if (pos.x () > topright.x ()) topright = ICOORD (pos.x (), topright.y ()); if (pos.y () > topright.y ()) topright = ICOORD (topright.x (), pos.y ()); pts.forward (); } while (!pts.at_first ()); ibl = ICOORD (botleft.x (), botleft.y ()); itr = ICOORD (topright.x (), topright.y ()); box = TBOX (ibl, itr); }
void POLY_BLOCK::move(ICOORD shift) { ICOORDELT *pt; //current point ICOORDELT_IT pts = &vertices; //iterator do { pt = pts.data (); *pt += shift; pts.forward (); } while (!pts.at_first ()); compute_bb(); }
void POLY_BLOCK::reflect_in_y_axis() { ICOORDELT *pt; // current point ICOORDELT_IT pts = &vertices; // Iterator. do { pt = pts.data(); pt->set_x(-pt->x()); pts.forward(); } while (!pts.at_first()); compute_bb(); }
BOOL8 POLY_BLOCK::overlap( // do polys overlap POLY_BLOCK *other) { inT16 count; //winding count ICOORDELT_IT it = &vertices; //iterator ICOORD vertex; if (!box.overlap (*(other->bounding_box ()))) return FALSE; //can't be any overlap /* see if a vertex of this is inside other */ do { vertex = *it.data (); //get winding number count = other->winding_number (vertex); if (count != INTERSECTING) if (count != 0) return (TRUE); it.forward (); } while (!it.at_first ()); /* see if a vertex of other is inside this */ //switch lists it.set_to_list (other->points ()); do { vertex = *it.data (); //try other way round count = winding_number (vertex); if (count != INTERSECTING) if (count != 0) return (TRUE); it.forward (); } while (!it.at_first ()); return FALSE; }
BOOL8 POLY_BLOCK::contains( //other outline POLY_BLOCK *other) { inT16 count; //winding count ICOORDELT_IT it = &vertices; //iterator ICOORD vertex; if (!box.overlap (*(other->bounding_box ()))) return FALSE; //can't be contained /* check that no vertex of this is inside other */ do { vertex = *it.data (); //get winding number count = other->winding_number (vertex); if (count != INTERSECTING) if (count != 0) return (FALSE); it.forward (); } while (!it.at_first ()); /* check that all vertices of other are inside this */ //switch lists it.set_to_list (other->points ()); do { vertex = *it.data (); //try other way round count = winding_number (vertex); if (count != INTERSECTING) if (count == 0) return (FALSE); it.forward (); } while (!it.at_first ()); return TRUE; }
void POLY_BLOCK::rotate(FCOORD rotation) { FCOORD pos; //current pos; ICOORDELT *pt; //current point ICOORDELT_IT pts = &vertices; //iterator do { pt = pts.data (); pos.set_x (pt->x ()); pos.set_y (pt->y ()); pos.rotate (rotation); pt->set_x ((inT16) (floor (pos.x () + 0.5))); pt->set_y ((inT16) (floor (pos.y () + 0.5))); pts.forward (); } while (!pts.at_first ()); compute_bb(); }