diff --git a/include/polylabel.h b/include/polylabel.h index 5d3805eb..de3a8bc7 100644 --- a/include/polylabel.h +++ b/include/polylabel.h @@ -111,18 +111,24 @@ Cell getCentroidCell(const Polygon& polygon) { double area = 0; double cx = 0, cy = 0; const auto& ring = polygon.outer(); + const Point& origin = ring.at(0); + const double ox = origin.get<0>(); + const double oy = origin.get<1>(); for (std::size_t i = 0, len = ring.size(), j = len - 1; i < len; j = i++) { const Point& a = ring[i]; const Point& b = ring[j]; - auto f = a.get<0>() * b.get<1>() - b.get<0>() * a.get<1>(); - cx += (a.get<0>() + b.get<0>()) * f; - cy += (a.get<1>() + b.get<1>()) * f; + const double ax = a.get<0>() - ox; + const double ay = a.get<1>() - oy; + const double bx = b.get<0>() - ox; + const double by = b.get<1>() - oy; + auto f = ax * by - bx * ay; + cx += (ax + bx) * f; + cy += (ay + by) * f; area += f * 3; } - Point c { cx, cy }; - return Cell(area == 0 ? ring.at(0) : Point { cx / area, cy / area }, 0, polygon); + return Cell(area == 0 ? ring.at(0) : Point { ox + cx / area, oy + cy / area }, 0, polygon); } } // namespace detail @@ -144,7 +150,11 @@ Point polylabel(const Polygon& polygon, double precision = 0.00001, bool debug = // a priority queue of cells in order of their "potential" (max distance to polygon) auto compareMax = [] (const Cell& a, const Cell& b) { - return a.max < b.max; + if (a.max != b.max) return a.max < b.max; + if (a.d != b.d) return a.d < b.d; + if (a.h != b.h) return a.h > b.h; + if (a.c.get<0>() != b.c.get<0>()) return a.c.get<0>() > b.c.get<0>(); + return a.c.get<1>() > b.c.get<1>(); }; using Queue = std::priority_queue, decltype(compareMax)>; Queue cellQueue(compareMax);