Polygon_2 remove_collinear(const Polygon_2& p, Number_type epsilon) { static log4cplus::Logger logger = log4cplus::Logger::getInstance("polygon_utils.remove_collinear"); LOG4CPLUS_TRACE(logger, pp(p)); if (!p.is_simple()) { stringstream ss; ss << "Polygon is not simple in remove_collinear: " << pp(p); throw logic_error(ss.str()); } Polygon_2::Vertex_circulator start = p.vertices_circulator(); Polygon_2::Vertex_circulator c = start; Polygon_2::Vertex_circulator n = c; Polygon_2::Vertex_circulator prev = c; ++n; --prev; Polygon_2 newp; do { Triangle_2 t(*prev, *c, *n); Number_type a = abs(t.area()); if (a > epsilon) // if (!CGAL::collinear(*prev, *c, *n)) newp.push_back(*c); else LOG4CPLUS_TRACE(logger, "Removing collinearity at " << pp(*c) << " area = " << a); ++prev; ++c; ++n; } while (c != start); return newp; }
static Point_2 centroid(const Polygon_2& poly) { assert(poly.size() >= 3); Polygon_2::Vertex_circulator vcir = poly.vertices_circulator(); Polygon_2::Vertex_circulator vend = vcir; Polygon_2::Vertex_circulator vnext = vcir; ++vnext; Vector_2 centre(0, 0); NT a(0), asum(0); do { a = (vcir->x() * vnext->y()) - (vnext->x() * vcir->y()); centre = centre + a * ((*vcir - CGAL::ORIGIN) + (*vnext - CGAL::ORIGIN)); // slow... asum += a; vcir = vnext; ++vnext; } while(vcir != vend); centre = centre / (asum * 3); return CGAL::ORIGIN + centre; }
bool is_strictly_convex(const Polygon_2& polygon, const boost::unordered_map<Point_3, boost::unordered_set<Segment_3_undirected> >& point2edges) { Polygon_2::Vertex_circulator start = polygon.vertices_circulator(); Polygon_2::Vertex_circulator c = start; Polygon_2::Vertex_circulator p = c; Polygon_2::Vertex_circulator n = c; --p; ++n; do { if (!CGAL::left_turn(*p, *c, *n) || !is_legal(*p, *c, *n, point2edges)) return false; ++p; ++c; ++n; } while (c != start); return true; }