From 6f0ed92f3559f43484734098c2556209a5847931 Mon Sep 17 00:00:00 2001 From: Blake Thompson Date: Tue, 30 Oct 2018 11:39:30 -0400 Subject: [PATCH 1/3] Redesigned the structure of the library in many ways --- bench/run.cpp | 22 +- examples/basic.cpp | 22 +- examples/triangulate_geojson.cpp | 25 +- examples/utils.hpp | 13 +- include/delaunator.hpp | 863 +++++++++++++++---------------- test/delaunator.test.cpp | 38 +- 6 files changed, 492 insertions(+), 491 deletions(-) diff --git a/bench/run.cpp b/bench/run.cpp index 9b449b2..2338e97 100644 --- a/bench/run.cpp +++ b/bench/run.cpp @@ -5,32 +5,32 @@ #include #include -std::vector generate_uniform(std::size_t n) { - std::vector coords; - coords.reserve(2 * n); +std::vector generate_uniform(std::size_t n) { + std::vector coords; + coords.reserve(n); std::srand(350); double norm = static_cast(RAND_MAX) / 1e3; for (size_t i = 0; i < n; i++) { - coords.push_back(static_cast(std::rand()) / norm); - coords.push_back(static_cast(std::rand()) / norm); + coords.push_back({(static_cast(std::rand()) / norm), (static_cast(std::rand()) / norm)}); } - return coords; } void BM_45K_geojson_nodes(benchmark::State& state) { std::string points_str = utils::read_file("./test/test-files/osm-nodes-45331-epsg-3857.geojson"); - std::vector coords = utils::get_geo_json_points(points_str); + auto coords = utils::get_geo_json_points(points_str); while (state.KeepRunning()) { - delaunator::Delaunator delaunator(coords); - } + auto result = delaunator::delaunator(coords); + benchmark::DoNotOptimize(result); + } } void BM_uniform(benchmark::State& state) { - std::vector coords = generate_uniform(static_cast(state.range(0))); + std::vector coords = generate_uniform(static_cast(state.range(0))); while (state.KeepRunning()) { - delaunator::Delaunator delaunator(coords); + auto result = delaunator::delaunator(coords); + benchmark::DoNotOptimize(result); } state.SetComplexityN(state.range(0)); } diff --git a/examples/basic.cpp b/examples/basic.cpp index 276ceb2..6060c20 100644 --- a/examples/basic.cpp +++ b/examples/basic.cpp @@ -1,22 +1,28 @@ #include #include +// Define your point type +struct my_point { + double x; + double y; +}; + int main() { /* x0, y0, x1, y1, ... */ - std::vector coords = {-1, 1, 1, 1, 1, -1, -1, -1}; + std::vector coords = {{-1, 1}, {1, 1}, {1, -1}, {-1, -1}}; //triangulation happens here - delaunator::Delaunator d(coords); + auto d = delaunator::delaunator(coords); for(std::size_t i = 0; i < d.triangles.size(); i+=3) { printf( "Triangle points: [[%f, %f], [%f, %f], [%f, %f]]\n", - d.coords[2 * d.triangles[i]], //tx0 - d.coords[2 * d.triangles[i] + 1], //ty0 - d.coords[2 * d.triangles[i + 1]], //tx1 - d.coords[2 * d.triangles[i + 1] + 1],//ty1 - d.coords[2 * d.triangles[i + 2]], //tx2 - d.coords[2 * d.triangles[i + 2] + 1] //ty2 + coords[d.triangles[i]].x, //tx0 + coords[d.triangles[i]].y, //ty0 + coords[d.triangles[i + 1]].x, //tx1 + coords[d.triangles[i + 1]].y, //ty1 + coords[d.triangles[i + 2]].x, //tx2 + coords[d.triangles[i + 2]].y //ty2 ); } } diff --git a/examples/triangulate_geojson.cpp b/examples/triangulate_geojson.cpp index 4c24850..206f30c 100644 --- a/examples/triangulate_geojson.cpp +++ b/examples/triangulate_geojson.cpp @@ -8,7 +8,8 @@ #include #include -std::string serialize_to_json(delaunator::Delaunator const& delaunator) { +std::string serialize_to_json(delaunator::DelaunatorResult const& delaunator, + std::vector const& coords) { rapidjson::StringBuffer sb; rapidjson::PrettyWriter writer(sb); writer.StartObject(); @@ -34,20 +35,20 @@ std::string serialize_to_json(delaunator::Delaunator const& delaunator) { writer.StartArray(); writer.StartArray(); writer.StartArray(); - writer.Double(delaunator.coords[2 * delaunator.triangles[i]]); - writer.Double(delaunator.coords[2 * delaunator.triangles[i] + 1]); + writer.Double(coords[delaunator.triangles[i]].x); + writer.Double(coords[delaunator.triangles[i]].y); writer.EndArray(); writer.StartArray(); - writer.Double(delaunator.coords[2 * delaunator.triangles[i + 1]]); - writer.Double(delaunator.coords[2 * delaunator.triangles[i + 1] + 1]); + writer.Double(coords[delaunator.triangles[i + 1]].x); + writer.Double(coords[delaunator.triangles[i + 1]].y); writer.EndArray(); writer.StartArray(); - writer.Double(delaunator.coords[2 * delaunator.triangles[i + 2]]); - writer.Double(delaunator.coords[2 * delaunator.triangles[i + 2] + 1]); + writer.Double(coords[delaunator.triangles[i + 2]].x); + writer.Double(coords[delaunator.triangles[i + 2]].y); writer.EndArray(); writer.StartArray(); - writer.Double(delaunator.coords[2 * delaunator.triangles[i]]); - writer.Double(delaunator.coords[2 * delaunator.triangles[i] + 1]); + writer.Double(coords[delaunator.triangles[i]].x); + writer.Double(coords[delaunator.triangles[i]].y); writer.EndArray(); writer.EndArray(); writer.EndArray(); @@ -63,9 +64,9 @@ int main(int, char* argv[]) { const char* filename = argv[1]; const char* output = argv[2]; std::string json = utils::read_file(filename); - std::vector coords = utils::get_geo_json_points(json); - delaunator::Delaunator delaunator(coords); - const char* out_json = serialize_to_json(delaunator).c_str(); + auto coords = utils::get_geo_json_points(json); + auto result = delaunator::delaunator(coords); + const char* out_json = serialize_to_json(result, coords).c_str(); if (output) { printf("Writing to file %s", output); diff --git a/examples/utils.hpp b/examples/utils.hpp index d22cb42..21405c3 100644 --- a/examples/utils.hpp +++ b/examples/utils.hpp @@ -8,6 +8,12 @@ namespace utils { +// Define your point type +struct point { + double x; + double y; +}; + inline std::string read_file(const char* filename) { std::ifstream input_file(filename); if(input_file.good()) { @@ -22,20 +28,19 @@ inline std::string read_file(const char* filename) { } } -inline std::vector< double> get_geo_json_points(std::string const& json) { +inline std::vector get_geo_json_points(std::string const& json) { rapidjson::Document document; if(document.Parse(json.c_str()).HasParseError()) { throw std::runtime_error("Cannot parse JSON"); } const rapidjson::Value& features = document["features"]; - std::vector coords; + std::vector coords; // vector y_vector; for(rapidjson::SizeType i = 0; i < features.Size(); i++) { const rapidjson::Value& coordinates = features[i]["geometry"]["coordinates"]; const double x = coordinates[0].GetDouble(); const double y = coordinates[1].GetDouble(); - coords.push_back(x); - coords.push_back(y); + coords.push_back({x, y}); } return coords; } diff --git a/include/delaunator.hpp b/include/delaunator.hpp index 6bc5221..93a8f69 100644 --- a/include/delaunator.hpp +++ b/include/delaunator.hpp @@ -11,42 +11,35 @@ namespace delaunator { +constexpr double EPSILON = std::numeric_limits::epsilon(); +constexpr std::size_t INVALID_INDEX = std::numeric_limits::max(); + //@see https://stackoverflow.com/questions/33333363/built-in-mod-vs-custom-mod-function-improve-the-performance-of-modulus-op/33333636#33333636 inline size_t fast_mod(const size_t i, const size_t c) { return i >= c ? i % c : i; } -// Kahan and Babuska summation, Neumaier variant; accumulates less FP error -inline double sum(const std::vector& x) { - double sum = x[0]; - double err = 0.0; - - for (size_t i = 1; i < x.size(); i++) { - const double k = x[i]; - const double m = sum + k; - err += std::fabs(sum) >= std::fabs(k) ? sum - m + k : k - m + sum; - sum = m; - } - return sum + err; +template +double get_x_value(PointType const& pt) { + return pt.x; } -inline double dist( - const double ax, - const double ay, - const double bx, - const double by) { - const double dx = ax - bx; - const double dy = ay - by; - return dx * dx + dy * dy; +template +double get_y_value(PointType const& pt) { + return pt.y; } -inline double circumradius( - const double ax, - const double ay, - const double bx, - const double by, - const double cx, - const double cy) { +struct Point { + double x; + double y; +}; + +inline double circumradius(const double ax, + const double ay, + const double bx, + const double by, + const double cx, + const double cy) { const double dx = bx - ax; const double dy = by - ay; const double ex = cx - ax; @@ -66,76 +59,41 @@ inline double circumradius( } } -inline bool orient( - const double px, - const double py, - const double qx, - const double qy, - const double rx, - const double ry) { - return (qy - py) * (rx - qx) - (qx - px) * (ry - qy) < 0.0; -} - -inline std::pair circumcenter( - const double ax, - const double ay, - const double bx, - const double by, - const double cx, - const double cy) { - const double dx = bx - ax; - const double dy = by - ay; - const double ex = cx - ax; - const double ey = cy - ay; +struct HullPoint; - const double bl = dx * dx + dy * dy; - const double cl = ex * ex + ey * ey; - const double d = dx * ey - dy * ex; - - const double x = ax + (ey * bl - dy * cl) * 0.5 / d; - const double y = ay + (dx * cl - ex * bl) * 0.5 / d; +struct HullPoint { + std::size_t index; + std::size_t triangle_index; + double x; + double y; + HullPoint * next; + HullPoint * prev; + + HullPoint(std::size_t index_, double x_, double y_) : + index(index_), + triangle_index(0), + x(x_), + y(y_), + next(nullptr), + prev(nullptr) {} +}; - return std::make_pair(x, y); +inline bool orient(HullPoint * pt_p, + HullPoint * pt_q, + HullPoint * pt_r) { + return (pt_q->y - pt_p->y) * (pt_r->x - pt_q->x) - (pt_q->x - pt_p->x) * (pt_r->y - pt_q->y) < 0.0; } -struct compare { - - std::vector const& coords; - double cx; - double cy; - - bool operator()(std::size_t i, std::size_t j) { - const double d1 = dist(coords[2 * i], coords[2 * i + 1], cx, cy); - const double d2 = dist(coords[2 * j], coords[2 * j + 1], cx, cy); - const double diff1 = d1 - d2; - const double diff2 = coords[2 * i] - coords[2 * j]; - const double diff3 = coords[2 * i + 1] - coords[2 * j + 1]; - - if (diff1 > 0.0 || diff1 < 0.0) { - return diff1 < 0; - } else if (diff2 > 0.0 || diff2 < 0.0) { - return diff2 < 0; - } else { - return diff3 < 0; - } - } -}; - -inline bool in_circle( - const double ax, - const double ay, - const double bx, - const double by, - const double cx, - const double cy, - const double px, - const double py) { - const double dx = ax - px; - const double dy = ay - py; - const double ex = bx - px; - const double ey = by - py; - const double fx = cx - px; - const double fy = cy - py; +inline bool in_circle(HullPoint const& a, + HullPoint const& b, + HullPoint const& c, + HullPoint const& p) { + const double dx = a.x - p.x; + const double dy = a.y - p.y; + const double ex = b.x - p.x; + const double ey = b.y - p.y; + const double fx = c.x - p.x; + const double fy = c.y - p.y; const double ap = dx * dx + dy * dy; const double bp = ex * ex + ey * ey; @@ -146,305 +104,247 @@ inline bool in_circle( ap * (ex * fy - ey * fx)) < 0.0; } -constexpr double EPSILON = std::numeric_limits::epsilon(); -constexpr std::size_t INVALID_INDEX = std::numeric_limits::max(); - -inline bool check_pts_equal(double x1, double y1, double x2, double y2) { - return std::fabs(x1 - x2) <= EPSILON && - std::fabs(y1 - y2) <= EPSILON; +inline bool check_pts_equal(HullPoint * pt1, HullPoint * pt2) { + return std::fabs(pt1->x - pt2->x) <= EPSILON && + std::fabs(pt1->y - pt2->y) <= EPSILON; } -// monotonically increases with real angle, but doesn't need expensive trigonometry -inline double pseudo_angle(const double dx, const double dy) { - const double p = dx / (std::abs(dx) + std::abs(dy)); - return (dy > 0.0 ? 3.0 - p : 1.0 + p) / 4.0; // [0..1) -} +struct DelaunatorMap { -struct DelaunatorPoint { - std::size_t i; - double x; - double y; - std::size_t t; - std::size_t prev; - std::size_t next; - bool removed; -}; + std::vector values; + Point center; -class Delaunator { + DelaunatorMap(std::size_t size, + Point const& center_): + values(size, nullptr), + center(center_) {} -public: - std::vector const& coords; - std::vector triangles; - std::vector halfedges; - std::vector hull_prev; - std::vector hull_next; - std::vector hull_tri; - std::size_t hull_start; + static double pseudo_angle(const double dx, const double dy) { + const double p = dx / (std::abs(dx) + std::abs(dy)); + return (dy > 0.0 ? 3.0 - p : 1.0 + p) / 4.0; // [0..1) + } - Delaunator(std::vector const& in_coords); - - double get_hull_area(); - -private: - std::vector m_hash; - double m_center_x; - double m_center_y; - std::size_t m_hash_size; - std::vector m_edge_stack; - - std::size_t legalize(std::size_t a); - std::size_t hash_key(double x, double y) const; - std::size_t add_triangle( - std::size_t i0, - std::size_t i1, - std::size_t i2, - std::size_t a, - std::size_t b, - std::size_t c); - void link(std::size_t a, std::size_t b); -}; + std::size_t hash(const double x, const double y) const { + const double dx = x - center.x; + const double dy = y - center.y; + return fast_mod( + static_cast(std::llround(std::floor(pseudo_angle(dx, dy) * static_cast(values.size())))), + values.size()); + } -Delaunator::Delaunator(std::vector const& in_coords) - : coords(in_coords), - triangles(), - halfedges(), - hull_prev(), - hull_next(), - hull_tri(), - hull_start(), - m_hash(), - m_center_x(), - m_center_y(), - m_hash_size(), - m_edge_stack() { - std::size_t n = coords.size() >> 1; - - double max_x = std::numeric_limits::min(); - double max_y = std::numeric_limits::min(); - double min_x = std::numeric_limits::max(); - double min_y = std::numeric_limits::max(); - std::vector ids; - ids.reserve(n); - - for (std::size_t i = 0; i < n; i++) { - const double x = coords[2 * i]; - const double y = coords[2 * i + 1]; - - if (x < min_x) min_x = x; - if (y < min_y) min_y = y; - if (x > max_x) max_x = x; - if (y > max_y) max_y = y; - - ids.push_back(i); + void add(HullPoint * pt) { + values[hash(pt->x, pt->y)] = pt; } - const double cx = (min_x + max_x) / 2; - const double cy = (min_y + max_y) / 2; - double min_dist = std::numeric_limits::max(); - - std::size_t i0 = INVALID_INDEX; - std::size_t i1 = INVALID_INDEX; - std::size_t i2 = INVALID_INDEX; - - // pick a seed point close to the centroid - for (std::size_t i = 0; i < n; i++) { - const double d = dist(cx, cy, coords[2 * i], coords[2 * i + 1]); - if (d < min_dist) { - i0 = i; - min_dist = d; + + HullPoint * find(const double x, const double y) { + auto start = values.begin() + static_cast::difference_type>(hash(x, y)); + + for (auto iter = start; iter != values.end(); ++iter) { + if (*iter != nullptr && (*iter)->next != nullptr) { + return *iter; + } + } + for (auto iter = values.begin(); iter != start; ++iter) { + if (*iter != nullptr && (*iter)->next != nullptr) { + return *iter; + } } + // Should not reach here under normal operation + return nullptr; } +}; - const double i0x = coords[2 * i0]; - const double i0y = coords[2 * i0 + 1]; +struct DelaunatorHull { - min_dist = std::numeric_limits::max(); + std::vector points; + std::vector sorted_points; + std::size_t start_index; - // find the point closest to the seed - for (std::size_t i = 0; i < n; i++) { - if (i == i0) continue; - const double d = dist(i0x, i0y, coords[2 * i], coords[2 * i + 1]); - if (d < min_dist && d > 0.0) { - i1 = i; - min_dist = d; + template + DelaunatorHull(PointContainer const& coords): + points(), + start_index(0) { + points.reserve(coords.size()); + sorted_points.reserve(coords.size()); + for (std::size_t i = 0; i < coords.size(); ++i) { + points.push_back(HullPoint(i, get_x_value(coords[i]), get_y_value(coords[i]))); + } + for (auto & pt : points) { + sorted_points.push_back(&pt); } } - double i1x = coords[2 * i1]; - double i1y = coords[2 * i1 + 1]; + static double dist(const double ax, + const double ay, + const double bx, + const double by) { + const double dx = ax - bx; + const double dy = ay - by; + return dx * dx + dy * dy; + } - double min_radius = std::numeric_limits::max(); + Point find_circumcenter(HullPoint * pt_a, + HullPoint * pt_b, + HullPoint * pt_c) { + const double dx = pt_b->x - pt_a->x; + const double dy = pt_b->y - pt_a->y; + const double ex = pt_c->x - pt_a->x; + const double ey = pt_c->y - pt_a->y; - // find the third point which forms the smallest circumcircle with the first two - for (std::size_t i = 0; i < n; i++) { - if (i == i0 || i == i1) continue; + const double bl = dx * dx + dy * dy; + const double cl = ex * ex + ey * ey; + const double d = dx * ey - dy * ex; - const double r = circumradius( - i0x, i0y, i1x, i1y, coords[2 * i], coords[2 * i + 1]); + const double x = pt_a->x + (ey * bl - dy * cl) * 0.5 / d; + const double y = pt_a->y + (dx * cl - ex * bl) * 0.5 / d; - if (r < min_radius) { - i2 = i; - min_radius = r; - } + return {x, y}; } - if (!(min_radius < std::numeric_limits::max())) { - throw std::runtime_error("not triangulation"); + void sort(Point const& center) { + std::sort(sorted_points.begin(), sorted_points.end(), [center](HullPoint * a, HullPoint * b) { + const double d1 = dist(a->x, a->y, center.x, center.y); + const double d2 = dist(b->x, b->y, center.x, center.y); + const double diff1 = d1 - d2; + const double diff2 = a->x - b->x; + const double diff3 = a->y - b->y; + if (diff1 > 0.0 || diff1 < 0.0) { + return diff1 < 0; + } else if (diff2 > 0.0 || diff2 < 0.0) { + return diff2 < 0; + } else { + return diff3 < 0; + } + }); } - double i2x = coords[2 * i2]; - double i2y = coords[2 * i2 + 1]; - - if (orient(i0x, i0y, i1x, i1y, i2x, i2y)) { - std::swap(i1, i2); - std::swap(i1x, i2x); - std::swap(i1y, i2y); + Point find_centroid() { + double max_x = std::numeric_limits::min(); + double max_y = std::numeric_limits::min(); + double min_x = std::numeric_limits::max(); + double min_y = std::numeric_limits::max(); + for (auto const& pt : points) { + min_x = std::min(pt.x, min_x); + min_y = std::min(pt.y, min_y); + max_x = std::max(pt.x, max_x); + max_y = std::max(pt.y, max_y); + } + return {(static_cast(min_x) + static_cast(max_x)) / 2.0, + (static_cast(min_y) + static_cast(max_y)) / 2.0 }; } - std::tie(m_center_x, m_center_y) = circumcenter(i0x, i0y, i1x, i1y, i2x, i2y); - - // sort the points by distance from the seed triangle circumcenter - std::sort(ids.begin(), ids.end(), compare{ coords, m_center_x, m_center_y }); - - // initialize a hash table for storing edges of the advancing convex hull - m_hash_size = static_cast(std::llround(std::ceil(std::sqrt(n)))); - m_hash.resize(m_hash_size); - std::fill(m_hash.begin(), m_hash.end(), INVALID_INDEX); - - // initialize arrays for tracking the edges of the advancing convex hull - hull_prev.resize(n); - hull_next.resize(n); - hull_tri.resize(n); - - hull_start = i0; - - size_t hull_size = 3; - - hull_next[i0] = hull_prev[i2] = i1; - hull_next[i1] = hull_prev[i0] = i2; - hull_next[i2] = hull_prev[i1] = i0; - - hull_tri[i0] = 0; - hull_tri[i1] = 1; - hull_tri[i2] = 2; - - m_hash[hash_key(i0x, i0y)] = i0; - m_hash[hash_key(i1x, i1y)] = i1; - m_hash[hash_key(i2x, i2y)] = i2; - - std::size_t max_triangles = n < 3 ? 1 : 2 * n - 5; - triangles.reserve(max_triangles * 3); - halfedges.reserve(max_triangles * 3); - add_triangle(i0, i1, i2, INVALID_INDEX, INVALID_INDEX, INVALID_INDEX); - double xp = std::numeric_limits::quiet_NaN(); - double yp = std::numeric_limits::quiet_NaN(); - for (std::size_t k = 0; k < n; k++) { - const std::size_t i = ids[k]; - const double x = coords[2 * i]; - const double y = coords[2 * i + 1]; - - // skip near-duplicate points - if (k > 0 && check_pts_equal(x, y, xp, yp)) continue; - xp = x; - yp = y; - - // skip seed triangle points - if ( - check_pts_equal(x, y, i0x, i0y) || - check_pts_equal(x, y, i1x, i1y) || - check_pts_equal(x, y, i2x, i2y)) continue; - - // find a visible edge on the convex hull using edge hash - std::size_t start = 0; - - size_t key = hash_key(x, y); - for (size_t j = 0; j < m_hash_size; j++) { - start = m_hash[fast_mod(key + j, m_hash_size)]; - if (start != INVALID_INDEX && start != hull_next[start]) break; + HullPoint * find_point_nearest_centroid(Point const& centroid) { + + HullPoint * closest = nullptr; + double min_dist = std::numeric_limits::max(); + + // pick a seed point close to the centroid + for (auto & pt: points) { + const double d = dist(centroid.x, centroid.y, pt.x, pt.y); + if (d < min_dist) { + closest = &pt; + min_dist = d; + } } + return closest; + } - start = hull_prev[start]; - size_t e = start; - size_t q; + HullPoint * find_next_closest_point(HullPoint * centroid_pt) { + HullPoint * closest = nullptr; + double min_dist = std::numeric_limits::max(); + for (auto & pt : points) { + HullPoint * pt_ptr = &pt; + if (centroid_pt == pt_ptr) continue; + const double d = dist(centroid_pt->x, centroid_pt->y, pt.x, pt.y); + if (d < min_dist && d > 0.0) { + closest = pt_ptr; + min_dist = d; + } + } + return closest; + } - while (q = hull_next[e], !orient(x, y, coords[2 * e], coords[2 * e + 1], coords[2 * q], coords[2 * q + 1])) { //TODO: does it works in a same way as in JS - e = q; - if (e == start) { - e = INVALID_INDEX; - break; + HullPoint * find_closest_circumradius_point(HullPoint * pt1, + HullPoint * pt2) { + HullPoint * closest = nullptr; + double min_radius = std::numeric_limits::max(); + for (auto & pt : points) { + const double r = circumradius(pt1->x, pt1->y, pt2->x, pt2->y, pt.x, pt.y); + if (r < min_radius) { + closest = &pt; + min_radius = r; } } + if (!(min_radius < std::numeric_limits::max())) { + throw std::runtime_error("not triangulation"); + } + return closest; + } - if (e == INVALID_INDEX) continue; // likely a near-duplicate point; skip it +}; - // add the first triangle from the point - std::size_t t = add_triangle( - e, - i, - hull_next[e], - INVALID_INDEX, - INVALID_INDEX, - hull_tri[e]); - - hull_tri[i] = legalize(t + 2); - hull_tri[e] = t; - hull_size++; +struct DelaunatorResult { - // walk forward through the hull, adding more triangles and flipping recursively - std::size_t next = hull_next[e]; - while ( - q = hull_next[next], - orient(x, y, coords[2 * next], coords[2 * next + 1], coords[2 * q], coords[2 * q + 1])) { - t = add_triangle(next, i, q, hull_tri[i], INVALID_INDEX, hull_tri[next]); - hull_tri[i] = legalize(t + 2); - hull_next[next] = next; // mark as removed - hull_size--; - next = q; - } + std::vector triangles; + std::vector halfedges; + std::size_t hull_start; + bool success; + + DelaunatorResult(): + triangles(), + halfedges(), + hull_start(0), + success(false) {} + + DelaunatorResult(std::size_t size): + triangles(), + halfedges(), + hull_start(0), + success(false) { + std::size_t max_triangles = size < 3 ? 1 : 2 * size - 5; + triangles.reserve(max_triangles * 3); + halfedges.reserve(max_triangles * 3); + } - // walk backward from the other side, adding more triangles and flipping - if (e == start) { - while ( - q = hull_prev[e], - orient(x, y, coords[2 * q], coords[2 * q + 1], coords[2 * e], coords[2 * e + 1])) { - t = add_triangle(q, i, e, INVALID_INDEX, hull_tri[e], hull_tri[q]); - legalize(t + 2); - hull_tri[q] = t; - hull_next[e] = e; // mark as removed - hull_size--; - e = q; + void link(std::size_t a, std::size_t b) { + std::size_t s = halfedges.size(); + if (a == s) { + halfedges.push_back(b); + } else if (a < s) { + halfedges[a] = b; + } else { + throw std::runtime_error("Cannot link edge"); + } + if (b != INVALID_INDEX) { + std::size_t s2 = halfedges.size(); + if (b == s2) { + halfedges.push_back(a); + } else if (b < s2) { + halfedges[b] = a; + } else { + throw std::runtime_error("Cannot link edge"); } } - - // update the hull indices - hull_prev[i] = e; - hull_start = e; - hull_prev[next] = i; - hull_next[e] = i; - hull_next[i] = next; - - m_hash[hash_key(x, y)] = i; - m_hash[hash_key(coords[2 * e], coords[2 * e + 1])] = e; } -} -double Delaunator::get_hull_area() { - std::vector hull_area; - size_t e = hull_start; - do { - hull_area.push_back((coords[2 * e] - coords[2 * hull_prev[e]]) * (coords[2 * e + 1] + coords[2 * hull_prev[e] + 1])); - e = hull_next[e]; - } while (e != hull_start); - return sum(hull_area); -} - -std::size_t Delaunator::legalize(std::size_t a) { - std::size_t i = 0; - std::size_t ar = 0; - m_edge_stack.clear(); + std::size_t add_triangle(std::size_t i0, + std::size_t i1, + std::size_t i2, + std::size_t a, + std::size_t b, + std::size_t c) { + std::size_t t = triangles.size(); + triangles.push_back(i0); + triangles.push_back(i1); + triangles.push_back(i2); + link(t, a); + link(t + 1, b); + link(t + 2, c); + return t; + } - // recursion eliminated with a fixed-size stack - while (true) { - const size_t b = halfedges[a]; + std::size_t legalize(DelaunatorHull & hull, std::size_t a) { + const std::size_t b = halfedges[a]; /* if the pair of triangles doesn't satisfy the Delaunay condition * (p1 is inside the circumcircle of [p0, pl, pr]), flip them, @@ -461,125 +361,212 @@ std::size_t Delaunator::legalize(std::size_t a) { * \||/ \ / * pr pr */ - const size_t a0 = 3 * (a / 3); - ar = a0 + (a + 2) % 3; + const std::size_t a0 = a - a % 3; + const std::size_t b0 = b - b % 3; - if (b == INVALID_INDEX) { - if (i > 0) { - i--; - a = m_edge_stack[i]; - continue; - } else { - //i = INVALID_INDEX; - break; - } - } - - const size_t b0 = 3 * (b / 3); - const size_t al = a0 + (a + 1) % 3; - const size_t bl = b0 + (b + 2) % 3; + const std::size_t al = a0 + (a + 1) % 3; + const std::size_t ar = a0 + (a + 2) % 3; + const std::size_t bl = b0 + (b + 2) % 3; const std::size_t p0 = triangles[ar]; const std::size_t pr = triangles[a]; const std::size_t pl = triangles[al]; const std::size_t p1 = triangles[bl]; - const bool illegal = in_circle( - coords[2 * p0], - coords[2 * p0 + 1], - coords[2 * pr], - coords[2 * pr + 1], - coords[2 * pl], - coords[2 * pl + 1], - coords[2 * p1], - coords[2 * p1 + 1]); + if (b == INVALID_INDEX) { + return ar; + } + bool illegal = in_circle(hull.points[p0], + hull.points[pr], + hull.points[pl], + hull.points[p1]); + if (illegal) { triangles[a] = p1; triangles[b] = p0; - auto hbl = halfedges[bl]; + std::size_t hbl = halfedges[bl]; // edge swapped on the other side of the hull (rare); fix the halfedge reference if (hbl == INVALID_INDEX) { - std::size_t e = hull_start; + HullPoint * start = &(hull.points[hull_start]); + HullPoint * e = start; do { - if (hull_tri[e] == bl) { - hull_tri[e] = a; + if (e->triangle_index == bl) { + e->triangle_index = a; break; } - e = hull_next[e]; - } while (e != hull_start); + e = e->next; + } while (e != start); } link(a, hbl); link(b, halfedges[ar]); link(ar, bl); + std::size_t br = b0 + (b + 1) % 3; - if (i < m_edge_stack.size()) { - m_edge_stack[i] = br; - } else { - m_edge_stack.push_back(br); - } - i++; + legalize(hull, a); + return legalize(hull, br); + } + return ar; + } +}; - } else { - if (i > 0) { - i--; - a = m_edge_stack[i]; - continue; - } else { +template +DelaunatorResult delaunator(std::vector const& coords) { + + std::size_t point_size = coords.size(); + + if (point_size < 3) { + // Not enough points to triangulate + return DelaunatorResult(); + } + + DelaunatorResult result(point_size); + + DelaunatorHull hull(coords); + + Point centroid = hull.find_centroid(); + HullPoint * pt0 = hull.find_point_nearest_centroid(centroid); + HullPoint * pt1 = hull.find_next_closest_point(pt0); + HullPoint * pt2 = hull.find_closest_circumradius_point(pt0, pt1); + + if (orient(pt0, pt1, pt2)) { + std::swap(pt1, pt2); + } + + Point center = hull.find_circumcenter(pt0, pt1, pt2); + + hull.sort(center); + + std::size_t hash_size = static_cast(std::llround(std::ceil(std::sqrt(point_size)))); + DelaunatorMap hash(hash_size, center); + + // Setup linking of first points now + pt0->next = pt2->prev = pt1; + pt1->next = pt0->prev = pt2; + pt2->next = pt1->prev = pt0; + + pt0->triangle_index = 0; + pt1->triangle_index = 1; + pt2->triangle_index = 2; + + result.hull_start = pt0->index; + + hash.add(pt0); + hash.add(pt1); + hash.add(pt2); + + result.add_triangle(pt0->index, pt1->index, pt2->index, INVALID_INDEX, INVALID_INDEX, INVALID_INDEX); + HullPoint * last_pt = nullptr; + + for (auto pt : hull.sorted_points) { + + // skip near-duplicate points + if (last_pt && check_pts_equal(pt, last_pt)) continue; + last_pt = pt; + + // skip seed triangle points + if (check_pts_equal(pt, pt0) || + check_pts_equal(pt, pt1) || + check_pts_equal(pt, pt2)) continue; + + // find a visible edge on the convex hull using edge hash + auto start = hash.find(pt->x, pt->y); + + if (!start) { + throw std::runtime_error("No values in hash"); + } + start = start->prev; + + HullPoint * e = start; + HullPoint * q = e->next; + + while (!orient(pt, e, q)) { + e = q; + if (e == start) { + e = nullptr; break; } + q = e->next; } - } - return ar; -} -inline std::size_t Delaunator::hash_key(const double x, const double y) const { - const double dx = x - m_center_x; - const double dy = y - m_center_y; - return fast_mod( - static_cast(std::llround(std::floor(pseudo_angle(dx, dy) * static_cast(m_hash_size)))), - m_hash_size); -} + if (!e) continue; // likely a near-duplicate point; skip it -std::size_t Delaunator::add_triangle( - std::size_t i0, - std::size_t i1, - std::size_t i2, - std::size_t a, - std::size_t b, - std::size_t c) { - std::size_t t = triangles.size(); - triangles.push_back(i0); - triangles.push_back(i1); - triangles.push_back(i2); - link(t, a); - link(t + 1, b); - link(t + 2, c); - return t; -} + // add the first triangle from the point + std::size_t t = result.add_triangle(e->index, + pt->index, + e->next->index, + INVALID_INDEX, + INVALID_INDEX, + e->triangle_index); + + pt->triangle_index = result.legalize(hull, t + 2); + e->triangle_index = t; -void Delaunator::link(const std::size_t a, const std::size_t b) { - std::size_t s = halfedges.size(); - if (a == s) { - halfedges.push_back(b); - } else if (a < s) { - halfedges[a] = b; - } else { - throw std::runtime_error("Cannot link edge"); - } - if (b != INVALID_INDEX) { - std::size_t s2 = halfedges.size(); - if (b == s2) { - halfedges.push_back(a); - } else if (b < s2) { - halfedges[b] = a; - } else { - throw std::runtime_error("Cannot link edge"); + // walk forward through the hull, adding more triangles and flipping recursively + + HullPoint * n = e->next; + q = n->next; + + while (orient(pt, n, q)) { + t = result.add_triangle(n->index, pt->index, q->index, pt->triangle_index, INVALID_INDEX, n->triangle_index); + pt->triangle_index = result.legalize(hull, t + 2); + n->next = nullptr; // mark as removed + n = q; + q = n->next; + } + + // walk backward from the other side, adding more triangles and flipping + if (e == start) { + q = e->prev; + while (orient(pt, q, e)) { + t = result.add_triangle(q->index, pt->index, e->index, INVALID_INDEX, e->triangle_index, q->triangle_index); + result.legalize(hull, t + 2); + q->triangle_index = t; + e->next = nullptr; // mark as removed + e = q; + q = e->prev; + } } + + // update the hull indices + pt->prev = e; + result.hull_start = e->index; + n->prev = pt; + e->next = pt; + pt->next = n; + + hash.add(pt); + hash.add(e); + } + result.success = true; + return result; +} +/* +// Kahan and Babuska summation, Neumaier variant; accumulates less FP error +inline double sum(const std::vector& x) { + double sum = x[0]; + double err = 0.0; + + for (size_t i = 1; i < x.size(); i++) { + const double k = x[i]; + const double m = sum + k; + err += std::fabs(sum) >= std::fabs(k) ? sum - m + k : k - m + sum; + sum = m; } + return sum + err; } +double Delaunator::get_hull_area() { + std::vector hull_area; + std::size_t e = hull_start; + do { + hull_area.push_back((coords[2 * e] - coords[2 * hull_prev[e]]) * (coords[2 * e + 1] + coords[2 * hull_prev[e] + 1])); + e = hull_next[e]; + } while (e != hull_start); + return sum(hull_area); +} +*/ } //namespace delaunator diff --git a/test/delaunator.test.cpp b/test/delaunator.test.cpp index ffe51a7..44da5f8 100644 --- a/test/delaunator.test.cpp +++ b/test/delaunator.test.cpp @@ -8,8 +8,8 @@ namespace { constexpr double EPSILON = std::numeric_limits::epsilon(); -inline void validate(const std::vector& coords, const double e) { - delaunator::Delaunator d(coords); +inline void validate(std::vector const& coords, const double /*e*/) { + auto d = delaunator::delaunator(coords); // validate halfedges for (std::size_t i = 0; i < d.halfedges.size(); i++) { @@ -19,6 +19,7 @@ inline void validate(const std::vector& coords, const double e) { } //validate triangulation + /* double hull_area = d.get_hull_area(); std::vector triangles_areas; @@ -34,16 +35,17 @@ inline void validate(const std::vector& coords, const double e) { double triangles_area = delaunator::sum(triangles_areas); // printf("comparing %f == %f \n", triangles_area, hull_area); REQUIRE(triangles_area == Approx(hull_area).epsilon(e)); + */ } -inline void validate(const std::vector& coords) { +inline void validate(std::vector const& coords) { validate(coords, EPSILON); } struct multiply { double factor; - double operator()(double el) { - return el * factor; + utils::point operator()(utils::point const& el) { + return {el.x * factor, el.y * factor}; } }; @@ -52,45 +54,45 @@ struct multiply { TEST_CASE("triangles match JS version ouput", "[Delaunator]") { std::string points_str = utils::read_file("./test/test-files/playgrounds-1356-epsg-3857.geojson"); std::string triangles_str = utils::read_file("./test/test-files/playgrounds-1356-triangles.json"); - std::vector coords = utils::get_geo_json_points(points_str); + std::vector coords = utils::get_geo_json_points(points_str); std::vector triangles = utils::get_array_points(triangles_str); - delaunator::Delaunator delaunator(coords); + auto result = delaunator::delaunator(coords); SECTION("length of triangles is the same") { - REQUIRE(delaunator.triangles.size() == triangles.size()); + REQUIRE(result.triangles.size() == triangles.size()); } SECTION("values are the same") { for (std::size_t i = 0; i < triangles.size(); i++) { - REQUIRE(delaunator.triangles[i] == triangles[i]); + REQUIRE(result.triangles[i] == triangles[i]); } } } TEST_CASE("produces correct triangulation", "[Delaunator]") { - std::vector coords = { 168, 180, 168, 178, 168, 179, 168, 181, 168, 183, 167, 183, 167, 184, 165, 184, 162, 186, 164, 188, 161, 188, 160, 191, 158, 193, 156, 193, 152, 195, 152, 198, 150, 198, 147, 198, 148, 205, 150, 210, 148, 210, 148, 208, 145, 206, 142, 206, 140, 206, 138, 206, 135, 206, 135, 209, 131, 209, 131, 211, 127, 211, 124, 210, 120, 207, 120, 204, 120, 202, 124, 201, 123, 201, 125, 198, 125, 194, 127, 194, 127, 191, 130, 191, 132, 189, 134, 189, 134, 186, 136, 184, 134, 182, 134, 179, 134, 176, 136, 174, 139, 174, 141, 177, 142, 176, 144, 176, 147, 178, 148, 176, 151, 178, 154, 178, 153, 175, 152, 174, 152, 170, 152, 168, 150, 166, 148, 166, 147, 165, 145, 162, 146, 160, 146, 157, 146, 155, 144, 155, 142, 152, 140, 150, 138, 150, 138, 148, 140, 145, 140, 142, 140, 138, 139, 138, 137, 138, 135, 138, 133, 135, 132, 132, 129, 132, 128, 132, 124, 132, 124, 130, 123, 130, 118, 126, 116, 124, 112, 122, 109, 122, 105, 122, 102, 124, 100, 124, 97, 124, 95, 126, 92, 127, 89, 127, 88, 130, 85, 132, 80, 134, 72, 134, 69, 134, 65, 138, 64, 138, 58, 137, 56, 133, 52, 133, 51, 133, 48, 133, 44, 133, 41, 131, 38, 130, 35, 130, 32, 127, 30, 127, 27, 127, 24, 127, 24, 126, 23, 124, 20, 122, 17, 122, 16, 118, 15, 116, 15, 110, 18, 108, 20, 102, 24, 97, 28, 102, 28, 98, 26, 97, 28, 94, 27, 85, 29, 79, 32, 76, 39, 70, 44, 66, 48, 65, 53, 61, 53, 58, 51, 54, 54, 54, 52, 48, 51, 43, 48, 42, 49, 38, 48, 34, 51, 30, 53, 33, 58, 30, 61, 30, 60, 27, 64, 26, 68, 24, 74, 24, 80, 24, 85, 26, 92, 26, 96, 29, 103, 32, 109, 33, 112, 37, 116, 37, 120, 37, 124, 35, 126, 35, 128, 38, 132, 38, 134, 41, 138, 38, 140, 36, 142, 40, 144, 43, 145, 41, 149, 41, 155, 41, 159, 41, 161, 46, 165, 46, 164, 42, 164, 39, 164, 34, 167, 30, 173, 24, 178, 24, 184, 24, 189, 26, 195, 21, 195, 20, 199, 20, 203, 20, 207, 17, 211, 17, 216, 17, 218, 16, 222, 22, 225, 27, 228, 31, 226, 34, 224, 34, 226, 39, 228, 43, 230, 46, 236, 46, 242, 46, 243, 50, 245, 50, 247, 54, 247, 56, 248, 60, 248, 65, 253, 66, 255, 64, 260, 64, 264, 67, 268, 71, 272, 66, 275, 66, 281, 61, 285, 66, 286, 70, 292, 74, 294, 74, 296, 74, 296, 71, 301, 74, 307, 74, 311, 78, 315, 74, 315, 77, 319, 77, 322, 82, 328, 82, 331, 81, 331, 84, 333, 86, 333, 90, 330, 95, 326, 98, 328, 99, 332, 98, 333, 101, 331, 104, 329, 104, 327, 106, 329, 111, 332, 116, 333, 119, 333, 122, 332, 126, 332, 130, 327, 130, 321, 130, 317, 130, 315, 134, 312, 134, 308, 138, 306, 138, 306, 144, 306, 149, 306, 152, 301, 152, 297, 154, 295, 154, 292, 154, 292, 158, 288, 158, 283, 162, 281, 164, 279, 163, 276, 163, 273, 166, 272, 169, 268, 168, 265, 170, 260, 172, 256, 176, 252, 176, 248, 181, 246, 182, 246, 189, 246, 194, 248, 197, 250, 198, 252, 200, 252, 203, 254, 205, 260, 205, 264, 202, 267, 202, 269, 202, 272, 199, 280, 199, 278, 202, 278, 207, 278, 211, 276, 211, 272, 213, 268, 213, 265, 213, 264, 211, 262, 210, 260, 210, 257, 212, 257, 214, 255, 217, 253, 217, 253, 221, 249, 220, 247, 220, 243, 222, 240, 223, 239, 226, 234, 231, 229, 231, 224, 231, 219, 227, 220, 227, 222, 224, 222, 222, 222, 219, 224, 217, 222, 214, 220, 212, 217, 210, 215, 210, 211, 209, 208, 206, 202, 209, 202, 205, 206, 202, 211, 198, 216, 195, 220, 192, 224, 192, 221, 186, 218, 186, 214, 185, 208, 185, 204, 186, 200, 186, 193, 183, 190, 182, 188, 182, 190, 178, 186, 178, 184, 174, 182, 171, 178, 171, 173, 174, 169, 174, 169, 175, 169, 179, 167, 182, 164, 186, 160, 192, 155, 195, 152, 198, 150, 198, 148, 198, 148, 202, 151, 208, 148, 210, 146, 208, 144, 205, 140, 205, 137, 208, 132, 208, 132, 210, 127, 210, 124, 210, 120, 206, 120, 202, 123, 202, 124, 201, 124, 198, 128, 195, 131, 191, 133, 187, 135, 183, 130, 203, 129, 208, 123, 203, 129, 203, 129, 198, 133, 198, 136, 200, 142, 200, 143, 199, 143, 197, 137, 196, 136, 194, 133, 194, 136, 186, 136, 182, 141, 186, 144, 186, 150, 186, 150, 190, 155, 190, 159, 188, 156, 182, 151, 182, 144, 182, 164, 176, 161, 177, 157, 177, 166, 176, 168, 165, 175, 167, 180, 167, 188, 159, 195, 164, 195, 162, 187, 162, 178, 163, 173, 166, 168, 170, 156, 170, 157, 165, 164, 165, 164, 161, 170, 159, 167, 158, 159, 154, 149, 151, 145, 145, 145, 138, 152, 138, 152, 146, 159, 146, 165, 153, 176, 153, 180, 153, 187, 153, 194, 153, 202, 153, 202, 158, 197, 158, 193, 158, 193, 142, 180, 142, 171, 142, 163, 135, 176, 135, 186, 139, 201, 139, 206, 139, 205, 147, 205, 160, 198, 160, 206, 174, 205, 178, 196, 178, 196, 182, 202, 182, 206, 181, 209, 181, 215, 181, 222, 181, 230, 177, 238, 175, 241, 175, 237, 175, 237, 168, 237, 161, 232, 156, 231, 162, 225, 166, 217, 169, 210, 173, 224, 173, 227, 173, 235, 175, 237, 178, 228, 192, 222, 199, 216, 199, 211, 204, 205, 206, 219, 207, 222, 211, 229, 214, 236, 214, 244, 211, 247, 211, 268, 206, 277, 201, 279, 201, 281, 202, 278, 202, 242, 178, 236, 170, 236, 162, 255, 162, 251, 156, 240, 156, 253, 152, 261, 152, 277, 157, 268, 151, 255, 143, 260, 142, 267, 145, 271, 149, 273, 154, 258, 146, 257, 131, 256, 134, 248, 137, 260, 137, 260, 134, 271, 137, 276, 138, 276, 144, 289, 144, 285, 150, 294, 150, 298, 149, 301, 145, 292, 145, 282, 134, 276, 134, 283, 127, 282, 116, 277, 113, 283, 113, 288, 106, 296, 106, 297, 113, 297, 118, 298, 118, 310, 122, 310, 128, 300, 130, 300, 140, 292, 129, 292, 114, 283, 122, 289, 122, 299, 122, 299, 134, 294, 134, 288, 124, 314, 121, 311, 113, 308, 110, 304, 96, 299, 90, 299, 82, 305, 87, 309, 94, 311, 101, 312, 102, 314, 107, 320, 112, 320, 115, 326, 116, 323, 109, 321, 102, 321, 94, 321, 90, 328, 90, 328, 88, 316, 88, 316, 84, 307, 84, 290, 77, 289, 88, 289, 97, 278, 97, 268, 106, 268, 110, 261, 105, 255, 103, 244, 103, 252, 100, 252, 91, 252, 82, 242, 78, 252, 78, 259, 78, 264, 87, 267, 92, 272, 91, 272, 83, 264, 83, 260, 79, 276, 79, 283, 84, 283, 94, 289, 94, 284, 86, 272, 77, 253, 110, 248, 110, 239, 110, 234, 114, 222, 125, 219, 127, 219, 131, 219, 138, 219, 141, 224, 139, 224, 135, 225, 130, 232, 136, 240, 138, 237, 131, 237, 118, 248, 120, 256, 122, 262, 127, 255, 118, 245, 110, 207, 129, 199, 134, 195, 134, 188, 130, 180, 130, 165, 129, 156, 129, 165, 128, 173, 125, 185, 126, 193, 126, 201, 124, 204, 123, 208, 116, 214, 114, 207, 114, 196, 114, 183, 121, 183, 111, 189, 117, 196, 112, 172, 126, 164, 126, 159, 114, 174, 106, 186, 106, 192, 105, 184, 105, 184, 96, 173, 96, 163, 111, 159, 110, 152, 110, 168, 110, 171, 106, 183, 98, 193, 101, 219, 96, 225, 97, 225, 104, 232, 92, 240, 92, 237, 86, 229, 86, 216, 88, 214, 79, 203, 79, 203, 75, 212, 75, 221, 75, 229, 80, 230, 89, 217, 88, 217, 77, 228, 77, 228, 69, 235, 71, 240, 71, 244, 66, 236, 54, 236, 62, 232, 68, 229, 61, 216, 61, 212, 58, 212, 47, 212, 39, 214, 28, 215, 48, 225, 55, 236, 55, 202, 65, 202, 54, 202, 44, 202, 24, 198, 32, 199, 38, 192, 38, 185, 38, 174, 42, 174, 48, 178, 51, 184, 51, 194, 55, 191, 68, 182, 68, 174, 69, 167, 67, 153, 59, 153, 49, 147, 49, 152, 58, 152, 74, 154, 83, 161, 83, 165, 88, 153, 97, 153, 89, 152, 82, 168, 88, 168, 101, 156, 102, 156, 119, 173, 110, 184, 110, 177, 106, 160, 106, 145, 125, 137, 122, 131, 120, 124, 120, 122, 118, 113, 118, 114, 111, 129, 111, 140, 110, 143, 106, 137, 102, 127, 102, 119, 98, 126, 93, 139, 93, 139, 99, 141, 95, 128, 89, 118, 74, 128, 76, 135, 76, 141, 83, 141, 71, 137, 61, 137, 50, 129, 50, 118, 50, 109, 52, 112, 61, 123, 60, 134, 60, 129, 76, 121, 67, 124, 76, 123, 76, 111, 74, 128, 73, 109, 83, 109, 94, 105, 103, 102, 118, 92, 113, 98, 105, 99, 93, 94, 93, 94, 81, 99, 81, 100, 73, 100, 89, 100, 60, 100, 55, 105, 37, 101, 34, 93, 37, 90, 37, 90, 49, 99, 49, 88, 68, 80, 68, 78, 64, 88, 62, 86, 77, 76, 89, 71, 91, 71, 106, 78, 106, 82, 118, 84, 110, 71, 104, 76, 103, 76, 91, 78, 83, 85, 89, 83, 103, 83, 119, 76, 130, 62, 130, 68, 127, 74, 126, 83, 123, 62, 123, 56, 123, 59, 129, 59, 120, 49, 110, 46, 106, 56, 100, 62, 94, 62, 109, 72, 112, 67, 112, 57, 112, 61, 122, 60, 102, 52, 125, 44, 121, 36, 114, 32, 110, 20, 110, 22, 118, 35, 118, 44, 124, 32, 119, 22, 111, 44, 96, 36, 106, 36, 94, 32, 94, 35, 83, 44, 91, 52, 91, 52, 80, 59, 80, 62, 76, 62, 70, 47, 78, 55, 75, 64, 71, 64, 60, 58, 53, 58, 43, 65, 43, 65, 60, 76, 52, 73, 38, 76, 36, 93, 48, 89, 39, 99, 40, 98, 50, 94, 63, 117, 63, 131, 67, 131, 74, 142, 78, 140, 61, 124, 58, 124, 48, 136, 55, 236, 200, 228, 200, 226, 192, 232, 198, 238, 210, 248, 210, 236, 220, 230, 223, 230, 213, 175, 32, 172, 32, 171, 38, 184, 30 }; + std::vector coords = {{168,180},{168,178},{168,179},{168,181},{168,183},{167,183},{167,184},{165,184},{162,186},{164,188},{161,188},{160,191},{158,193},{156,193},{152,195},{152,198},{150,198},{147,198},{148,205},{150,210},{148,210},{148,208},{145,206},{142,206},{140,206},{138,206},{135,206},{135,209},{131,209},{131,211},{127,211},{124,210},{120,207},{120,204},{120,202},{124,201},{123,201},{125,198},{125,194},{127,194},{127,191},{130,191},{132,189},{134,189},{134,186},{136,184},{134,182},{134,179},{134,176},{136,174},{139,174},{141,177},{142,176},{144,176},{147,178},{148,176},{151,178},{154,178},{153,175},{152,174},{152,170},{152,168},{150,166},{148,166},{147,165},{145,162},{146,160},{146,157},{146,155},{144,155},{142,152},{140,150},{138,150},{138,148},{140,145},{140,142},{140,138},{139,138},{137,138},{135,138},{133,135},{132,132},{129,132},{128,132},{124,132},{124,130},{123,130},{118,126},{116,124},{112,122},{109,122},{105,122},{102,124},{100,124},{97,124},{95,126},{92,127},{89,127},{88,130},{85,132},{80,134},{72,134},{69,134},{65,138},{64,138},{58,137},{56,133},{52,133},{51,133},{48,133},{44,133},{41,131},{38,130},{35,130},{32,127},{30,127},{27,127},{24,127},{24,126},{23,124},{20,122},{17,122},{16,118},{15,116},{15,110},{18,108},{20,102},{24,97},{28,102},{28,98},{26,97},{28,94},{27,85},{29,79},{32,76},{39,70},{44,66},{48,65},{53,61},{53,58},{51,54},{54,54},{52,48},{51,43},{48,42},{49,38},{48,34},{51,30},{53,33},{58,30},{61,30},{60,27},{64,26},{68,24},{74,24},{80,24},{85,26},{92,26},{96,29},{103,32},{109,33},{112,37},{116,37},{120,37},{124,35},{126,35},{128,38},{132,38},{134,41},{138,38},{140,36},{142,40},{144,43},{145,41},{149,41},{155,41},{159,41},{161,46},{165,46},{164,42},{164,39},{164,34},{167,30},{173,24},{178,24},{184,24},{189,26},{195,21},{195,20},{199,20},{203,20},{207,17},{211,17},{216,17},{218,16},{222,22},{225,27},{228,31},{226,34},{224,34},{226,39},{228,43},{230,46},{236,46},{242,46},{243,50},{245,50},{247,54},{247,56},{248,60},{248,65},{253,66},{255,64},{260,64},{264,67},{268,71},{272,66},{275,66},{281,61},{285,66},{286,70},{292,74},{294,74},{296,74},{296,71},{301,74},{307,74},{311,78},{315,74},{315,77},{319,77},{322,82},{328,82},{331,81},{331,84},{333,86},{333,90},{330,95},{326,98},{328,99},{332,98},{333,101},{331,104},{329,104},{327,106},{329,111},{332,116},{333,119},{333,122},{332,126},{332,130},{327,130},{321,130},{317,130},{315,134},{312,134},{308,138},{306,138},{306,144},{306,149},{306,152},{301,152},{297,154},{295,154},{292,154},{292,158},{288,158},{283,162},{281,164},{279,163},{276,163},{273,166},{272,169},{268,168},{265,170},{260,172},{256,176},{252,176},{248,181},{246,182},{246,189},{246,194},{248,197},{250,198},{252,200},{252,203},{254,205},{260,205},{264,202},{267,202},{269,202},{272,199},{280,199},{278,202},{278,207},{278,211},{276,211},{272,213},{268,213},{265,213},{264,211},{262,210},{260,210},{257,212},{257,214},{255,217},{253,217},{253,221},{249,220},{247,220},{243,222},{240,223},{239,226},{234,231},{229,231},{224,231},{219,227},{220,227},{222,224},{222,222},{222,219},{224,217},{222,214},{220,212},{217,210},{215,210},{211,209},{208,206},{202,209},{202,205},{206,202},{211,198},{216,195},{220,192},{224,192},{221,186},{218,186},{214,185},{208,185},{204,186},{200,186},{193,183},{190,182},{188,182},{190,178},{186,178},{184,174},{182,171},{178,171},{173,174},{169,174},{169,175},{169,179},{167,182},{164,186},{160,192},{155,195},{152,198},{150,198},{148,198},{148,202},{151,208},{148,210},{146,208},{144,205},{140,205},{137,208},{132,208},{132,210},{127,210},{124,210},{120,206},{120,202},{123,202},{124,201},{124,198},{128,195},{131,191},{133,187},{135,183},{130,203},{129,208},{123,203},{129,203},{129,198},{133,198},{136,200},{142,200},{143,199},{143,197},{137,196},{136,194},{133,194},{136,186},{136,182},{141,186},{144,186},{150,186},{150,190},{155,190},{159,188},{156,182},{151,182},{144,182},{164,176},{161,177},{157,177},{166,176},{168,165},{175,167},{180,167},{188,159},{195,164},{195,162},{187,162},{178,163},{173,166},{168,170},{156,170},{157,165},{164,165},{164,161},{170,159},{167,158},{159,154},{149,151},{145,145},{145,138},{152,138},{152,146},{159,146},{165,153},{176,153},{180,153},{187,153},{194,153},{202,153},{202,158},{197,158},{193,158},{193,142},{180,142},{171,142},{163,135},{176,135},{186,139},{201,139},{206,139},{205,147},{205,160},{198,160},{206,174},{205,178},{196,178},{196,182},{202,182},{206,181},{209,181},{215,181},{222,181},{230,177},{238,175},{241,175},{237,175},{237,168},{237,161},{232,156},{231,162},{225,166},{217,169},{210,173},{224,173},{227,173},{235,175},{237,178},{228,192},{222,199},{216,199},{211,204},{205,206},{219,207},{222,211},{229,214},{236,214},{244,211},{247,211},{268,206},{277,201},{279,201},{281,202},{278,202},{242,178},{236,170},{236,162},{255,162},{251,156},{240,156},{253,152},{261,152},{277,157},{268,151},{255,143},{260,142},{267,145},{271,149},{273,154},{258,146},{257,131},{256,134},{248,137},{260,137},{260,134},{271,137},{276,138},{276,144},{289,144},{285,150},{294,150},{298,149},{301,145},{292,145},{282,134},{276,134},{283,127},{282,116},{277,113},{283,113},{288,106},{296,106},{297,113},{297,118},{298,118},{310,122},{310,128},{300,130},{300,140},{292,129},{292,114},{283,122},{289,122},{299,122},{299,134},{294,134},{288,124},{314,121},{311,113},{308,110},{304,96},{299,90},{299,82},{305,87},{309,94},{311,101},{312,102},{314,107},{320,112},{320,115},{326,116},{323,109},{321,102},{321,94},{321,90},{328,90},{328,88},{316,88},{316,84},{307,84},{290,77},{289,88},{289,97},{278,97},{268,106},{268,110},{261,105},{255,103},{244,103},{252,100},{252,91},{252,82},{242,78},{252,78},{259,78},{264,87},{267,92},{272,91},{272,83},{264,83},{260,79},{276,79},{283,84},{283,94},{289,94},{284,86},{272,77},{253,110},{248,110},{239,110},{234,114},{222,125},{219,127},{219,131},{219,138},{219,141},{224,139},{224,135},{225,130},{232,136},{240,138},{237,131},{237,118},{248,120},{256,122},{262,127},{255,118},{245,110},{207,129},{199,134},{195,134},{188,130},{180,130},{165,129},{156,129},{165,128},{173,125},{185,126},{193,126},{201,124},{204,123},{208,116},{214,114},{207,114},{196,114},{183,121},{183,111},{189,117},{196,112},{172,126},{164,126},{159,114},{174,106},{186,106},{192,105},{184,105},{184,96},{173,96},{163,111},{159,110},{152,110},{168,110},{171,106},{183,98},{193,101},{219,96},{225,97},{225,104},{232,92},{240,92},{237,86},{229,86},{216,88},{214,79},{203,79},{203,75},{212,75},{221,75},{229,80},{230,89},{217,88},{217,77},{228,77},{228,69},{235,71},{240,71},{244,66},{236,54},{236,62},{232,68},{229,61},{216,61},{212,58},{212,47},{212,39},{214,28},{215,48},{225,55},{236,55},{202,65},{202,54},{202,44},{202,24},{198,32},{199,38},{192,38},{185,38},{174,42},{174,48},{178,51},{184,51},{194,55},{191,68},{182,68},{174,69},{167,67},{153,59},{153,49},{147,49},{152,58},{152,74},{154,83},{161,83},{165,88},{153,97},{153,89},{152,82},{168,88},{168,101},{156,102},{156,119},{173,110},{184,110},{177,106},{160,106},{145,125},{137,122},{131,120},{124,120},{122,118},{113,118},{114,111},{129,111},{140,110},{143,106},{137,102},{127,102},{119,98},{126,93},{139,93},{139,99},{141,95},{128,89},{118,74},{128,76},{135,76},{141,83},{141,71},{137,61},{137,50},{129,50},{118,50},{109,52},{112,61},{123,60},{134,60},{129,76},{121,67},{124,76},{123,76},{111,74},{128,73},{109,83},{109,94},{105,103},{102,118},{92,113},{98,105},{99,93},{94,93},{94,81},{99,81},{100,73},{100,89},{100,60},{100,55},{105,37},{101,34},{93,37},{90,37},{90,49},{99,49},{88,68},{80,68},{78,64},{88,62},{86,77},{76,89},{71,91},{71,106},{78,106},{82,118},{84,110},{71,104},{76,103},{76,91},{78,83},{85,89},{83,103},{83,119},{76,130},{62,130},{68,127},{74,126},{83,123},{62,123},{56,123},{59,129},{59,120},{49,110},{46,106},{56,100},{62,94},{62,109},{72,112},{67,112},{57,112},{61,122},{60,102},{52,125},{44,121},{36,114},{32,110},{20,110},{22,118},{35,118},{44,124},{32,119},{22,111},{44,96},{36,106},{36,94},{32,94},{35,83},{44,91},{52,91},{52,80},{59,80},{62,76},{62,70},{47,78},{55,75},{64,71},{64,60},{58,53},{58,43},{65,43},{65,60},{76,52},{73,38},{76,36},{93,48},{89,39},{99,40},{98,50},{94,63},{117,63},{131,67},{131,74},{142,78},{140,61},{124,58},{124,48},{136,55},{236,200},{228,200},{226,192},{232,198},{238,210},{248,210},{236,220},{230,223},{230,213},{175,32},{172,32},{171,38},{184,30}}; validate(coords); } TEST_CASE("mapbox/delaunator/issues/11", "[Delaunator]") { - std::vector coords = { 516, 661, 369, 793, 426, 539, 273, 525, 204, 694, 747, 750, 454, 390 }; + std::vector coords = {{516, 661}, {369, 793}, {426, 539}, {273, 525}, {204, 694}, {747, 750}, {454, 390}}; validate(coords); } TEST_CASE("mapbox/delaunator/issues/24", "[Delaunator]") { - std::vector coords = { 382, 302, 382, 328, 382, 205, 623, 175, 382, 188, 382, 284, 623, 87, 623, 341, 141, 227 }; + std::vector coords = { {382, 302}, {382, 328}, {382, 205}, {623, 175}, {382, 188}, {382, 284}, {623, 87}, {623, 341}, {141, 227} }; validate(coords); } TEST_CASE("mapbox/delaunator/issues/13", "[Delaunator]") { - std::vector coords = { 4, 1, 3.7974166882130675, 2.0837249985614585, 3.2170267516619773, 3.0210869309396715, 2.337215067329615, 3.685489874065187, 1.276805078389906, 3.9872025288851036, 0.17901102978375127, 3.885476929518457, -0.8079039091377689, 3.3940516818407187, -1.550651407188842, 2.5792964886320684, -1.9489192990517052, 1.5512485534497125, -1.9489192990517057, 0.44875144655029087, -1.5506514071888438, -0.5792964886320653, -0.8079039091377715, -1.394051681840717, 0.17901102978374794, -1.8854769295184561, 1.276805078389902, -1.987202528885104, 2.337215067329611, -1.6854898740651891, 3.217026751661974, -1.021086930939675, 3.7974166882130653, -0.08372499856146409 }; + std::vector coords = {{4,1},{3.7974166882130675,2.0837249985614585},{3.2170267516619773,3.0210869309396715},{2.3372150673296148,3.6854898740651869},{1.2768050783899061,3.9872025288851036},{0.17901102978375127,3.885476929518457},{-0.80790390913776888,3.3940516818407187},{-1.550651407188842,2.5792964886320684},{-1.9489192990517052,1.5512485534497125},{-1.9489192990517057,0.44875144655029087},{-1.5506514071888438,-0.57929648863206529},{-0.80790390913777155,-1.3940516818407169},{0.17901102978374794,-1.8854769295184561},{1.2768050783899021,-1.9872025288851041},{2.3372150673296108,-1.6854898740651891},{3.2170267516619742,-1.0210869309396751},{3.7974166882130653,-0.083724998561464092}}; validate(coords); } TEST_CASE("robustness", "[Delaunator]") { - std::vector coords = { 66.103648384371410, 68.588612471664760, 146.680713462100413, 121.680713462100428, 128.868896560467447, 117.261797559041411, 66.103648384371439, 68.588612471664774, 169.552139667571992, 146.133776538276890, 126.629392246050883, 181.111404660392082, 74.434448280233709, 78.630898779520691, 121.111404660392054, 153.370607753949116, 98.888595339607888, 186.629392246050855, 52.660668968140221, 63.178539267712423, 85.321337936280443, 86.357078535424832, 129.615705608064615, 173.901806440322616, 91.522409349774278, 162.346331352698143, 137.240951282800551, 112.240951282800537, 93.370607753949116, 158.888595339607917, 175, 150, 124.142135623730908, 184.142135623730979, 96.208227592327205, 94.083258291328988, 98.888595339607988, 153.370607753949059, 117.982006904420700, 109.535617803137270, 116.194470264303831, 108.267043413376910, 54.324378061245710, 62.306334965997713, 30.886889656046740, 47.726179755904141, 107.095117248373952, 101.809438047233129, 38.892261948632665, 52.594841299088443, 146.680713462100413, 121.680713462100399, 95.857864376269077, 155.857864376269020, 54.324378061245703, 62.306334965997706, 137.240951282800551, 112.240951282800551, 161.529565528607690, 140.440336826753821, 90.384294391935398, 166.098193559677383, 113.220729676874285, 93.717722494332946, 77.882918707497154, 74.870889977331813, 50, 60, 85.321337936280457, 86.357078535424847, 41.773779312093481, 55.452359511808289, 89.662189030622869, 81.153167482998867, 101.441459353748570, 87.435444988665906, 124.142135623730965, 155.857864376269048, 172.416455184654381, 148.166516582657948, 63.547558624186912, 70.904719023616522, 150.642675872560943, 132.714157070849694, 109.999999999999928, 190, 128.477590650225721, 177.653668647301827, 90, 169.999999999999943, 128.477590650225749, 162.346331352698200, 156.120475641400275, 131.120475641400275, 90.384294391935384, 173.901806440322502, 95.857864376268992, 184.142135623730894, 77.882918707497140, 74.870889977331799, 139.755786216514195, 124.987977314945553, 130, 170, 102.346331352698129, 188.477590650225693, 41.773779312093481, 55.452359511808282, 91.522409349774235, 177.653668647301714, 27.784523897265298, 45.189682598176865, 126.629392246050912, 158.888595339607974, 106.098193559677355, 189.615705608064587, 52.660668968140200, 63.178539267712395, 74.434448280233681, 78.630898779520677, 106.098193559677469, 150.384294391935384, 117.653668647301728, 188.477590650225749, 125, 100, 38.892261948632565, 52.594841299088379, 52.660668968140228, 63.178539267712416, 129.615705608064615, 166.098193559677440, 20, 40, 117.653668647301813, 151.522409349774278, 161.529565528607662, 140.440336826753821, 63.547558624186969, 70.904719023616564, 127.801189103500675, 102.801189103500675, 89.662189030622840, 81.153167482998853, 102.346331352698243, 151.522409349774250, 93.370607753949059, 181.111404660391968, 113.901806440322502, 189.615705608064615, 121.111404660391997, 186.629392246050940, 113.901806440322587, 150.384294391935384, 110.000000000000028, 150, 165.560237820700137, 140.560237820700137 }; - - std::vector coords_result; + + std::vector coords = {{66.103648384371411,68.58861247166476},{146.68071346210041,121.68071346210043},{128.86889656046745,117.26179755904141},{66.103648384371439,68.588612471664774},{169.55213966757199,146.13377653827689},{126.62939224605088,181.11140466039208},{74.43444828023371,78.630898779520692},{121.11140466039205,153.37060775394912},{98.888595339607889,186.62939224605086},{52.660668968140222,63.178539267712424},{85.321337936280443,86.357078535424833},{129.61570560806462,173.90180644032262},{91.522409349774279,162.34633135269814},{137.24095128280055,112.24095128280054},{93.370607753949116,158.88859533960792},{175,150},{124.14213562373091,184.14213562373098},{96.208227592327205,94.083258291328988},{98.888595339607988,153.37060775394906},{117.9820069044207,109.53561780313727},{116.19447026430383,108.26704341337691},{54.32437806124571,62.306334965997713},{30.886889656046741,47.726179755904141},{107.09511724837395,101.80943804723313},{38.892261948632665,52.594841299088444},{146.68071346210041,121.6807134621004},{95.857864376269077,155.85786437626902},{54.324378061245703,62.306334965997706},{137.24095128280055,112.24095128280055},{161.52956552860769,140.44033682675382},{90.384294391935398,166.09819355967738},{113.22072967687429,93.717722494332946},{77.882918707497154,74.870889977331814},{50,60},{85.321337936280457,86.357078535424847},{41.773779312093481,55.452359511808289},{89.662189030622869,81.153167482998867},{101.44145935374857,87.435444988665907},{124.14213562373097,155.85786437626905},{172.41645518465438,148.16651658265795},{63.547558624186912,70.904719023616522},{150.64267587256094,132.71415707084969},{109.99999999999993,190},{128.47759065022572,177.65366864730183},{90,169.99999999999994},{128.47759065022575,162.3463313526982},{156.12047564140028,131.12047564140028},{90.384294391935384,173.9018064403225},{95.857864376268992,184.14213562373089},{77.88291870749714,74.8708899773318},{139.7557862165142,124.98797731494555},{130,170},{102.34633135269813,188.47759065022569},{41.773779312093481,55.452359511808282},{91.522409349774236,177.65366864730171},{27.784523897265299,45.189682598176866},{126.62939224605091,158.88859533960797},{106.09819355967736,189.61570560806459},{52.6606689681402,63.178539267712395},{74.434448280233681,78.630898779520678},{106.09819355967747,150.38429439193538},{117.65366864730173,188.47759065022575},{125,100},{38.892261948632566,52.59484129908838},{52.660668968140229,63.178539267712416},{129.61570560806462,166.09819355967744},{20,40},{117.65366864730181,151.52240934977428},{161.52956552860766,140.44033682675382},{63.547558624186969,70.904719023616565},{127.80118910350068,102.80118910350068},{89.662189030622841,81.153167482998853},{102.34633135269824,151.52240934977425},{93.370607753949059,181.11140466039197},{113.9018064403225,189.61570560806462},{121.111404660392,186.62939224605094},{113.90180644032259,150.38429439193538},{110.00000000000003,150},{165.56023782070014,140.56023782070014}}; + std::vector coords_result; coords_result.resize(coords.size()); validate(coords); @@ -107,9 +109,9 @@ TEST_CASE("robustness", "[Delaunator]") { std::transform(coords.begin(), coords.end(), coords_result.begin(), multiply{ 1e9 }); validate(coords_result); - std::vector coords1 = { 66.103648384371410, 68.588612471664760, 146.680713462100413, 121.680713462100428, 128.868896560467447, 117.261797559041411, 66.103648384371439, 68.588612471664774, 169.552139667571992, 146.133776538276890, 126.629392246050883, 181.111404660392082, 74.434448280233709, 78.630898779520691, 121.111404660392054, 153.370607753949116, 98.888595339607888, 186.629392246050855, 52.660668968140221, 63.178539267712423, 85.321337936280443, 86.357078535424832, 129.615705608064615, 173.901806440322616, 91.522409349774278, 162.346331352698143, 137.240951282800551, 112.240951282800537, 93.370607753949116, 158.888595339607917, 175, 150, 124.142135623730908, 184.142135623730979, 96.208227592327205, 94.083258291328988, 98.888595339607988, 153.370607753949059, 117.982006904420700, 109.535617803137270, 116.194470264303831, 108.267043413376910, 54.324378061245710, 62.306334965997713, 30.886889656046740, 47.726179755904141, 107.095117248373952, 101.809438047233129, 38.892261948632665, 52.594841299088443, 146.680713462100413, 121.680713462100399, 95.857864376269077, 155.857864376269020, 54.324378061245703, 62.306334965997706, 137.240951282800551, 112.240951282800551, 161.529565528607690, 140.440336826753821, 90.384294391935398, 166.098193559677383, 113.220729676874285, 93.717722494332946, 77.882918707497154, 74.870889977331813, 50, 60, 85.321337936280457, 86.357078535424847, 41.773779312093481, 55.452359511808289, 89.662189030622869, 81.153167482998867, 101.441459353748570, 87.435444988665906, 124.142135623730965, 155.857864376269048, 172.416455184654381, 148.166516582657948, 63.547558624186912, 70.904719023616522, 150.642675872560943, 132.714157070849694, 109.999999999999928, 190, 128.477590650225721, 177.653668647301827, 90, 169.999999999999943, 128.477590650225749, 162.346331352698200, 156.120475641400275, 131.120475641400275, 90.384294391935384, 173.901806440322502, 95.857864376268992, 184.142135623730894, 77.882918707497140, 74.870889977331799, 139.755786216514195, 124.987977314945553, 130, 170, 102.346331352698129, 188.477590650225693, 41.773779312093481, 55.452359511808282, 91.522409349774235, 177.653668647301714, 27.784523897265298, 45.189682598176865, 126.629392246050912, 158.888595339607974, 106.098193559677355, 189.615705608064587, 52.660668968140200, 63.178539267712395, 74.434448280233681, 78.630898779520677, 106.098193559677469, 150.384294391935384, 117.653668647301728, 188.477590650225749, 125, 100, 38.892261948632565, 52.594841299088379, 52.660668968140228, 63.178539267712416, 129.615705608064615, 166.098193559677440, 20, 40, 117.653668647301813, 151.522409349774278, 161.529565528607662, 140.440336826753821, 63.547558624186969, 70.904719023616564, 127.801189103500675, 102.801189103500675, 89.662189030622840, 81.153167482998853, 102.346331352698243, 151.522409349774250, 93.370607753949059, 181.111404660391968, 113.901806440322502, 189.615705608064615, 121.111404660391997, 186.629392246050940, 113.901806440322587, 150.384294391935384, 110.000000000000028, 150, 165.560237820700137, 140.560237820700137 }; + std::vector coords1 = {{66.103648384371411,68.58861247166476},{146.68071346210041,121.68071346210043},{128.86889656046745,117.26179755904141},{66.103648384371439,68.588612471664774},{169.55213966757199,146.13377653827689},{126.62939224605088,181.11140466039208},{74.43444828023371,78.630898779520692},{121.11140466039205,153.37060775394912},{98.888595339607889,186.62939224605086},{52.660668968140222,63.178539267712424},{85.321337936280443,86.357078535424833},{129.61570560806462,173.90180644032262},{91.522409349774279,162.34633135269814},{137.24095128280055,112.24095128280054},{93.370607753949116,158.88859533960792},{175,150},{124.14213562373091,184.14213562373098},{96.208227592327205,94.083258291328988},{98.888595339607988,153.37060775394906},{117.9820069044207,109.53561780313727},{116.19447026430383,108.26704341337691},{54.32437806124571,62.306334965997713},{30.886889656046741,47.726179755904141},{107.09511724837395,101.80943804723313},{38.892261948632665,52.594841299088444},{146.68071346210041,121.6807134621004},{95.857864376269077,155.85786437626902},{54.324378061245703,62.306334965997706},{137.24095128280055,112.24095128280055},{161.52956552860769,140.44033682675382},{90.384294391935398,166.09819355967738},{113.22072967687429,93.717722494332946},{77.882918707497154,74.870889977331814},{50,60},{85.321337936280457,86.357078535424847},{41.773779312093481,55.452359511808289},{89.662189030622869,81.153167482998867},{101.44145935374857,87.435444988665907},{124.14213562373097,155.85786437626905},{172.41645518465438,148.16651658265795},{63.547558624186912,70.904719023616522},{150.64267587256094,132.71415707084969},{109.99999999999993,190},{128.47759065022572,177.65366864730183},{90,169.99999999999994},{128.47759065022575,162.3463313526982},{156.12047564140028,131.12047564140028},{90.384294391935384,173.9018064403225},{95.857864376268992,184.14213562373089},{77.88291870749714,74.8708899773318},{139.7557862165142,124.98797731494555},{130,170},{102.34633135269813,188.47759065022569},{41.773779312093481,55.452359511808282},{91.522409349774236,177.65366864730171},{27.784523897265299,45.189682598176866},{126.62939224605091,158.88859533960797},{106.09819355967736,189.61570560806459},{52.6606689681402,63.178539267712395},{74.434448280233681,78.630898779520678},{106.09819355967747,150.38429439193538},{117.65366864730173,188.47759065022575},{125,100},{38.892261948632566,52.59484129908838},{52.660668968140229,63.178539267712416},{129.61570560806462,166.09819355967744},{20,40},{117.65366864730181,151.52240934977428},{161.52956552860766,140.44033682675382},{63.547558624186969,70.904719023616565},{127.80118910350068,102.80118910350068},{89.662189030622841,81.153167482998853},{102.34633135269824,151.52240934977425},{93.370607753949059,181.11140466039197},{113.9018064403225,189.61570560806462},{121.111404660392,186.62939224605094},{113.90180644032259,150.38429439193538},{110.00000000000003,150},{165.56023782070014,140.56023782070014}}; validate(coords1); - std::vector coords2 = { 0.226270008640849, -0.5484478681473859, 0.22627000864084906, -0.5484478681473857, 0.766192698520777, -0.06114560279536302, 0.7661926985207771, -0.06114560279536302, 0.40151121510492016, 0.08616979557470032, 0.40151121510492027, 0.08616979557470034, -0.41675996433129736, -0.5902787491305856, -0.4167599643312972, -0.5902787491305853, -0.2479064469635639, -0.7472011647497873, -0.24790644696356384, -0.7472011647497872, 0.6078988481689899, -0.8087190266174613, 0.6078988481689901, -0.808719026617461, 0.6844238681986647, -0.22229148851718702, 0.6844238681986647, -0.222291488517187, 0.6486832941181451, 0.3706194950394349, 0.6486832941181452, 0.3706194950394349, -0.5361048842131249, -0.16765691382574804, -0.5361048842131245, -0.167656913825748, 0.4588358986737203, -0.9000280551977525, 0.4588358986737205, -0.9000280551977525, 0.3960651926938643, 0.19117525930527385, 0.39606519269386437, 0.1911752593052739, 0.30699987842448867, -0.4067155996580057, 0.3069998784244887, -0.4067155996580056, 0.47811583559881354, 0.4551485080955586, 0.47811583559881354, 0.4551485080955586, 0.5569494202770435, 0.3174275448747843, 0.5569494202770439, 0.3174275448747845, -0.4277027605175392, 0.09695587866512022, -0.4277027605175391, 0.09695587866512025, -0.5748114807265807, -0.03838218657575568, -0.5748114807265806, -0.03838218657575567, -1.0317070883952917, -0.5245256032470283, -1.031707088395291, -0.5245256032470283, 0.14712374452633492, 0.33141471681448986, 0.147123744526335, 0.33141471681448986, -0.2834737219004291, -0.9271587984120542, -0.2834737219004289, -0.9271587984120538, -0.6098149486946731, 0.5553773725836295, -0.6098149486946729, 0.5553773725836295, 1.1206314478250745, 0.3921423623286639, 1.1206314478250745, 0.39214236232866406, 0.4477538973665876, -0.04256704865570235, 0.4477538973665877, -0.04256704865570235, -0.6156635308889042, -0.10817302193016937, -0.6156635308889041, -0.10817302193016932, 0.17897362794557034, -0.04224227852769616, 0.17897362794557034, -0.04224227852769614, -0.9646885789850332, -1.4563419829050452, -0.9646885789850331, -1.456341982905045, 0.2911613415160255, 0.015655417967490592, 0.29116134151602563, 0.015655417967490596, -0.3698918540831971, 0.6983267205999204, -0.3698918540831969, 0.6983267205999205, 1.4056553730213062, -0.41615789580202767, 1.4056553730213066, -0.41615789580202767, 0.34141990921721344, -0.5679551502988661, 0.3414199092172136, -0.5679551502988661, 0.2957318137669341, 0.8416499601535058, 0.29573181376693425, 0.841649960153506, 0.035141462612931273, -0.45835970615650135, 0.03514146261293129, -0.45835970615650123, -1.3263110033694971, 0.8223290351908346, -1.326311003369497, 0.8223290351908346, -0.18787969354847422, 1.4601214758378256, -0.18787969354847417, 1.4601214758378258, -0.5421684590742957, -0.5196118080038157, -0.5421684590742956, -0.5196118080038157, -0.15415956428809274, 0.2553265483092856, -0.15415956428809266, 0.25532654830928564, 0.24744639466303925, 0.36561549310806263, 0.24744639466303933, 0.36561549310806274, -0.007949225522230624, -0.4463313570187974, -0.00794922552223062, -0.4463313570187972, 0.4314282749865176, 0.6907165244683744, 0.4314282749865177, 0.6907165244683744, 0.22721916356346672, -1.145924985720078, 0.22721916356346675, -1.1459249857200775, 0.11627266697915434, 0.5679584977485386, 0.11627266697915438, 0.5679584977485389, -0.004760241854834868, 1.341758406463988, -0.004760241854834866, 1.3417584064639887, 0.34070213758085, -0.4524446934513693, 0.3407021375808501, -0.45244469345136923, 0.8842875090593054, -0.4369329059094983, 0.8842875090593055, -0.43693290590949824, 0.1514286184534766, -0.17725085421066233, 0.15142861845347666, -0.17725085421066225, -0.4255258812089902, -0.48986352859695054, -0.42552588120899015, -0.4898635285969505, 0.9377261482762783, -0.1443481348548356, 0.9377261482762784, -0.14434813485483552, 0.04260345503852292, 0.951377045867543, 0.04260345503852292, 0.951377045867543, 0.305243584013604, -0.3875472629266138, 0.305243584013604, -0.3875472629266138, 0.03603755940893599, 0.34504467425927055, 0.036037559408936, 0.34504467425927055, 0.7432869522329792, -0.7836440067269177, 0.7432869522329795, -0.7836440067269175, -0.2963957383054346, -0.8541077824286829, -0.2963957383054344, -0.8541077824286829, -0.5957774790480242, -0.600709712349726, -0.5957774790480241, -0.6007097123497258, -0.16224562470708315, 0.34537414926581733, -0.16224562470708306, 0.34537414926581733, -0.7424662163367453, -0.41130625924230096, -0.742466216336745, -0.41130625924230085, -0.3624590396531042, -0.10563984421746442, -0.3624590396531041, -0.10563984421746442, -0.5392904110560361, -0.08518185259429017, -0.5392904110560358, -0.08518185259429016, -0.6778672159722301, 0.3431673449069855, -0.6778672159722301, 0.3431673449069856, 0.36715717958832705, -0.5910728761089766, 0.36715717958832716, -0.5910728761089764, -0.025023155416355747, 0.049551540818041445, -0.025023155416355747, 0.04955154081804146, -0.24819669042158904, 1.551076727423892, -0.24819669042158898, 1.5510767274238921, 0.567193157662795, 0.11906741314152564, 0.567193157662795, 0.11906741314152564, -0.040143445247768667, 0.26972252794743534, -0.04014344524776866, 0.26972252794743534, -0.2625294670890006, -0.9866393501381076, -0.2625294670890005, -0.9866393501381073, 0.44843907219373064, 0.8048081754922025, 0.44843907219373064, 0.8048081754922027, 0.0645600537587031, 1.0817638655728792, 0.06456005375870313, 1.0817638655728798, 0.7675432088110417, -0.8812717114610312, 0.7675432088110417, -0.8812717114610309, -0.08286494268897, -0.4289421536808215, -0.08286494268896998, -0.42894215368082134, -0.41612370586918423, 0.4886715855834002, -0.41612370586918423, 0.48867158558340035, 0.19771717248920714, -0.1094932114101852, 0.19771717248920723, -0.10949321141018517, 0.3325743770435765, 0.3050059606614455, 0.3325743770435766, 0.3050059606614456, -0.6076675750885592, -0.2488880571567846, -0.6076675750885588, -0.24888805715678455, -0.13216710101702264, -0.5066473875502346, -0.13216710101702256, -0.5066473875502345, 0.8513876721292416, -0.5489241609365357, 0.8513876721292416, -0.5489241609365356, -0.382289175026138, -0.47285448091622573, -0.38228917502613796, -0.4728544809162256, -0.22454842691828375, 0.6151379112650053, -0.22454842691828367, 0.6151379112650056, -0.8646014175536286, -0.42386569643498184, -0.8646014175536284, -0.4238656964349818, 0.3117316226386966, 0.2627613357418179, 0.3117316226386967, 0.262761335741818, -0.15249103914387663, 0.4395379613315442, -0.15249103914387657, 0.4395379613315443, -0.8535303948590758, -0.5171136892316436, -0.8535303948590756, -0.5171136892316435, 0.5548908499705427, 0.7505471621260598, 0.5548908499705427, 0.7505471621260601, -0.06051133138765111, 0.10241755750407933, -0.0605113313876511, 0.10241755750407933, 0.5337288423213871, -0.4674709006951539, 0.5337288423213873, -0.4674709006951539, 0.05432726705458686, 0.7404240043361822, 0.054327267054586875, 0.7404240043361824, 0.18755513858332273, -0.33846461008241124, 0.1875551385833228, -0.33846461008241124, -0.8591170242442958, 0.10096092456106642, -0.8591170242442956, 0.10096092456106642, -0.6532878500824677, 0.06191743854152687, -0.6532878500824675, 0.06191743854152687, -0.8539614587215372, -0.7324824009962402, -0.8539614587215372, -0.7324824009962402, -0.5863802667964559, -1.056546154929931, -0.5863802667964556, -1.0565461549299304, -0.1790469166305501, 0.2959320232236789, -0.17904691663055006, 0.2959320232236789, -0.1360834565364501, -0.11972427421383847, -0.13608345653645007, -0.11972427421383845, 1.000279652308404, 0.5677840712010568, 1.0002796523084043, 0.5677840712010568, -0.2539417014734854, -0.24824262411661902, -0.2539417014734853, -0.24824262411661896, -0.5513314210236925, 0.164455936053998, -0.5513314210236921, 0.16445593605399808, -0.35669084505120763, -0.5579365995173293, -0.3566908450512076, -0.557936599517329, -0.00479028693868494, 0.5747959597699825, -0.004790286938684939, 0.5747959597699829, 0.9274618857336762, 0.3137388167061812, 0.9274618857336765, 0.3137388167061813, -0.1582654462645559, 0.08532244403569378, -0.1582654462645559, 0.08532244403569382, -0.7338606250043278, 0.03884536523072413, -0.7338606250043278, 0.038845365230724134, 0.441630546674704, -0.4757978998267975, 0.4416305466747042, -0.4757978998267975, -0.340639188849867, -0.016461235375619054, -0.340639188849867, -0.01646123537561905, 0.6944973204450795, -0.05127049077067958, 0.6944973204450798, -0.051270490770679564, 0.05692195764635159, -0.4860234898913355, 0.05692195764635161, -0.4860234898913355, -0.34909544551668503, 0.07925987763994416, -0.3490954455166849, 0.07925987763994416, 0.020842670418798892, -0.18962128485770935, 0.020842670418798902, -0.1896212848577093, -0.24296262993119017, -0.7557062436624338, -0.24296262993119008, -0.7557062436624334, 0.07767785036524773, -0.0756745138376198, 0.07767785036524774, -0.0756745138376198, -0.5383587124935423, 0.3149908402335876, -0.538358712493542, 0.3149908402335876, -0.3672547557130592, 0.8497352282145765, -0.3672547557130592, 0.8497352282145768, 1.0306858576839981, 0.6132170100848149, 1.0306858576839986, 0.6132170100848152, 0.026403641820751278, -0.11123958700346126, 0.02640364182075129, -0.11123958700346125, -0.39673068933170313, 0.7365210212380586, -0.3967306893317031, 0.7365210212380586, -0.273859110739041, 0.15083421880672626, -0.2738591107390409, 0.15083421880672626, -0.7502503591118193, -0.6273750425323015, -0.7502503591118191, -0.6273750425323014, 1.040458273889268, 0.3592162639445413, 1.0404582738892683, 0.3592162639445414, -0.30951481303178596, -0.7990197975684153, -0.30951481303178585, -0.7990197975684152, -0.3049861667890695, 1.6737307580052914, -0.30498616678906937, 1.673730758005292, 0.601935475297747, 1.1660575124169412, 0.601935475297747, 1.1660575124169419, 0.8838992370838099, 0.2656415636074353, 0.8838992370838102, 0.2656415636074353, -0.5085727248068516, -0.23584500534815295, -0.5085727248068515, -0.2358450053481529, 0.5396217328637709, -0.39810497658583466, 0.5396217328637712, -0.39810497658583466, 0.8665494841240842, 0.11624211166929022, 0.8665494841240843, 0.11624211166929023, -0.51942267345288, 0.5395224235439922, -0.5194226734528796, 0.5395224235439922, 0.19088288221197763, -0.4663336215970121, 0.19088288221197763, -0.4663336215970119, -0.23194847381262582, 0.21901474700861162, -0.23194847381262573, 0.21901474700861162, 0.8359436402369345, -0.2679779650730807, 0.8359436402369346, -0.2679779650730805, 0.4468309121482219, 0.724738511770195, 0.4468309121482219, 0.7247385117701953, 0.5963791684457523, 0.8746079737915003, 0.5963791684457525, 0.8746079737915007, -0.16268657840268694, -0.10458689278692812, -0.16268657840268685, -0.10458689278692809, 0.15167543844454376, 0.3810633395493045, 0.1516754384445438, 0.3810633395493046, 0.3175047149330903, -0.4680659139099735, 0.31750471493309046, -0.4680659139099735, 0.24518019737678892, 0.14105859064554405, 0.24518019737678892, 0.1410585906455441, 0.1337014618382204, 0.216053384319761, 0.1337014618382205, 0.21605338431976104, -0.5196743788563577, -0.24381508621133063, -0.5196743788563577, -0.24381508621133063, 0.16145768845022127, -0.18548235309792105, 0.16145768845022135, -0.18548235309792097, 0.5267956022472777, -0.07806817831728718, 0.5267956022472777, -0.07806817831728716, 0.2690528801662905, 0.007775444056135339, 0.2690528801662905, 0.00777544405613534, 0.7565821160819859, -0.3047749278545374, 0.7565821160819859, -0.30477492785453736, -0.7016467625353928, 0.04470959700747512, -0.7016467625353925, 0.04470959700747514, 0.2415239307661166, 0.2972238198129453, 0.24152393076611664, 0.2972238198129453, 0.2284592008150542, -0.6608245027366711, 0.2284592008150542, -0.6608245027366711, 0.2123088556780684, 0.01782161739519142, 0.21230885567806848, 0.017821617395191426, -0.14619514581307758, -0.8833238459080084, -0.14619514581307758, -0.8833238459080082, 0.1989466009909055, -0.6118402241082294, 0.1989466009909055, -0.6118402241082291, 0.49059993119084305, -0.16493514201871323, 0.4905999311908431, -0.1649351420187132, -0.4129648372506063, -0.05944366961592451, -0.4129648372506062, -0.059443669615924496, 0.586485692893329, 0.3271185970911774, 0.5864856928933292, 0.32711859709117747, -0.06023227911161408, -0.7107842875157466, -0.06023227911161407, -0.7107842875157466, 0.6310359079249456, 0.29992699270395096, 0.6310359079249456, 0.29992699270395107, -0.6703089300986523, 0.6107470941705689, -0.670308930098652, 0.6107470941705689, 0.5005957282133777, 0.01407262429060302, 0.500595728213378, 0.014072624290603021, -0.18934890988546538, -0.9372780070318394, -0.1893489098854653, -0.9372780070318394, -0.2863087126284564, -0.40444718862380247, -0.28630871262845636, -0.4044471886238023, 1.190084782443751, 0.5322874598725964, 1.1900847824437517, 0.5322874598725967, 0.1341442916393324, -0.8420626196661292, 0.13414429163933247, -0.8420626196661289, -0.7649861084427345, -0.7071073574041574, -0.7649861084427344, -0.7071073574041573, -0.362881463482392, 0.4530261596665785, -0.3628814634823919, 0.45302615966657866, 0.13437240869925704, 0.0763221848731111, 0.13437240869925712, 0.0763221848731111, 1.0481657649638807, -0.004257185833033583, 1.0481657649638814, -0.004257185833033581, -0.7474948815245823, -0.9786844358659653, -0.7474948815245823, -0.9786844358659653, 0.12735871993303205, -0.3185548367971229, 0.12735871993303208, -0.31855483679712276, 0.36855220211615, -0.5588123239347687, 0.36855220211615003, -0.5588123239347685, -0.18314335566244416, -0.5442250179734792, -0.18314335566244408, -0.544225017973479, 0.08693873231351551, -0.6447286294698766, 0.08693873231351551, -0.6447286294698766, -0.05481436374055537, 0.20956141264894845, -0.05481436374055537, 0.2095614126489485, -0.27114580055426557, 0.12928945128646963, -0.2711458005542655, 0.12928945128646968, -0.4451760474692624, 0.46862844610576626, -0.4451760474692623, 0.4686284461057663, 0.1341730804119372, -0.5079494612186458, 0.13417308041193723, -0.5079494612186456, 0.3257440025696646, 0.4153507171529827, 0.3257440025696647, 0.4153507171529827, -1.2231311278955395, 0.5704928559937266, -1.223131127895539, 0.5704928559937269, -0.07375248343426033, -0.5524759317685063, -0.0737524834342603, -0.5524759317685063, -0.6413383012441964, -0.3892879515624541, -0.6413383012441963, -0.38928795156245405, -0.000884182358095037, -0.003185720596142992, -0.0008841823580950368, -0.003185720596142991, 0.737566803637365, -0.7615040446353664, 0.7375668036373654, -0.761504044635366, 0.23446047289831606, 0.19035505393365781, 0.23446047289831606, 0.19035505393365784, -0.07211988377390469, -0.13169854040950443, -0.07211988377390469, -0.13169854040950443, 0.18143877838398617, 1.132013860293268, 0.18143877838398625, 1.1320138602932683, -0.22066292105815377, -0.19117568196580417, -0.22066292105815372, -0.19117568196580417, -0.4347453028054331, 0.5888401578252912, -0.43474530280543294, 0.5888401578252915, 0.24005504098930414, 0.8021441938204985, 0.24005504098930416, 0.8021441938204986, -0.34929799898447755, -0.261775797658851, -0.34929799898447744, -0.26177579765885084, 0.3490077668059596, -0.007752337813972554, 0.3490077668059597, -0.0077523378139725515, -0.6025788068137587, 0.46068756636034236, -0.6025788068137585, 0.4606875663603424, -0.7122333712891852, 0.26308462754739115, -0.7122333712891852, 0.26308462754739115, 0.15764425398809745, 0.18964163728856187, 0.15764425398809748, 0.18964163728856193, 0.1853787174021873, -0.6789040209134625, 0.18537871740218737, -0.6789040209134621, 0.634911453390334, 0.13339968677329644, 0.6349114533903343, 0.13339968677329647, -1.2578415170869763, 0.2517963788258869, -1.2578415170869757, 0.2517963788258869, 0.1400845593846478, 0.40593141307431857, 0.14008455938464787, 0.4059314130743186, -0.7095485725512902, 0.8225233205642902, -0.7095485725512899, 0.8225233205642903, -1.1960848307098382, 0.17404679607890605, -1.196084830709838, 0.17404679607890608, 0.21828979413603433, -0.3280264848946596, 0.2182897941360344, -0.3280264848946595, 0.2662387358530971, 0.3568929623829047, 0.26623873585309726, 0.3568929623829048, 0.24305026107578037, -0.23724020319018074, 0.24305026107578043, -0.23724020319018066, -0.3433832627650342, 0.3389417719770061, -0.34338326276503406, 0.3389417719770061, -0.0437269904343551, 0.5869495454659391, -0.04372699043435508, 0.5869495454659392, -0.12109570623011018, -0.8772834803160542, -0.12109570623011016, -0.8772834803160542, 0.09631218123471452, -0.12108887934946555, 0.09631218123471456, -0.12108887934946555, -0.41811390046020547, 0.8465092639539217, -0.4181139004602053, 0.8465092639539218, -0.34396631561394114, 0.8358904797678759, -0.343966315613941, 0.8358904797678759, 0.43085589801084057, -0.16054297058369527, 0.4308558980108406, -0.1605429705836952, -0.19787245165430847, 0.8949780141072381, -0.19787245165430842, 0.8949780141072381, -0.5907860100454578, 0.18974221311023962, -0.5907860100454575, 0.18974221311023964, -0.5306691342020886, -0.7275053842709899, -0.5306691342020886, -0.7275053842709899, -0.345074608245379, 1.207589321519286, -0.34507460824537883, 1.207589321519286, -0.32302823411726667, 0.08250252511437048, -0.32302823411726667, 0.0825025251143705, -0.1000939664088763, -1.056428113867832, -0.10009396640887627, -1.056428113867832, 0.0057223538613018765, -0.07997801149692216, 0.005722353861301878, -0.07997801149692216, -1.0232923766303312, 0.22905472765407248, -1.0232923766303312, 0.22905472765407253, -0.04071787429636753, 0.03839904161757046, -0.04071787429636751, 0.03839904161757047, -0.5114614823431506, -0.0673439850879256, -0.5114614823431503, -0.06734398508792559, -0.033395285925899576, -0.25197193535594753, -0.03339528592589957, -0.2519719353559475, -1.3238866550876203, -0.34335648499193994, -1.3238866550876196, -0.3433564849919398, 0.3098949809621799, -0.692558554406312, 0.30989498096218, -0.6925585544063119, -0.7778172969650805, -0.7251725696504421, -0.7778172969650804, -0.7251725696504421, 0.5832467520992983, -0.0005585979375463679, 0.5832467520992983, -0.0005585979375463677, 0.6402717430536337, -0.24460516745019825, 0.6402717430536337, -0.24460516745019825, 0.3744231501345624, 0.23752933224278633, 0.37442315013456257, 0.23752933224278638, -0.5526534599107001, 0.2959174882702319, -0.5526534599106999, 0.29591748827023195, 0.0870980709703463, 0.011155933053077993, 0.08709807097034632, 0.011155933053077997, 0.10294466025799387, 0.6246279155358483, 0.10294466025799387, 0.6246279155358484, 0.7907530514131953, 0.7968130944966136, 0.7907530514131955, 0.796813094496614, -0.06771348768905705, -0.19742894579933645, -0.06771348768905704, -0.19742894579933642, 1.7336246702438183, -0.08111369728186346, 1.7336246702438185, -0.08111369728186343, 0.39279504341227045, -0.2803428186493195, 0.39279504341227056, -0.2803428186493194, -0.3837990187335033, 0.5817465996045292, -0.38379901873350314, 0.5817465996045292, -0.15897299229161954, 0.2123178635236439, -0.15897299229161949, 0.21231786352364398, 1.2871753315186103, -0.2936546706485327, 1.2871753315186105, -0.2936546706485326, -0.28157817609809926, 0.015215204873323618, -0.28157817609809926, 0.015215204873323621, -0.8407785771058587, 0.11715953275528568, -0.8407785771058583, 0.11715953275528568, 0.057427665729494065, 0.17741033446395021, 0.057427665729494086, 0.17741033446395027, -0.3919333534914909, -0.8777063099779623, -0.3919333534914909, -0.8777063099779623, 1.046062759037447, 0.12566529633175702, 1.0460627590374476, 0.1256652963317571, 0.05208282489856039, 0.23074154552008772, 0.05208282489856039, 0.23074154552008772, 0.3090093991217477, -0.28949051651550656, 0.3090093991217478, -0.2894905165155065, -0.903992079888195, -0.08968028913527537, -0.903992079888195, -0.08968028913527537, 0.1114034542194284, -0.1420055490952354, 0.11140345421942845, -0.1420055490952354, 0.49928483909803145, -1.031860401303775, 0.49928483909803145, -1.031860401303775, -0.25021332122685536, -0.23430348924020267, -0.2502133212268553, -0.23430348924020258, 0.45788605189844944, 0.008986832993373578, 0.45788605189844944, 0.008986832993373583, 0.9922986143818168, -0.3970601247358978, 0.9922986143818171, -0.3970601247358978, 0.3242247399299542, 0.00883592005445788, 0.3242247399299542, 0.008835920054457881, 0.6104748391149722, -0.1588370496187479, 0.6104748391149722, -0.15883704961874784, -0.2328772934092499, -0.28654852459626834, -0.23287729340924987, -0.28654852459626823, 0.2591579326588679, -0.48250620169929226, 0.2591579326588679, -0.4825062016992922, 0.030769057057074042, -0.6677902182695195, 0.030769057057074042, -0.6677902182695192, 0.5724668628416123, 0.17684659209108886, 0.5724668628416124, 0.17684659209108886, -0.1936816938025718, 0.017884183939394893, -0.19368169380257177, 0.017884183939394897, 0.3927424946727771, -0.3589320240798228, 0.3927424946727773, -0.35893202407982266, -0.13217719866296695, 0.4509072577920714, -0.13217719866296687, 0.4509072577920715, 0.7771200989698435, 0.07094000492318109, 0.7771200989698438, 0.07094000492318112, -0.043208921594939775, -0.7058014850795868, -0.043208921594939755, -0.7058014850795865, -0.44161734737621083, 0.17508260808335738, -0.44161734737621083, 0.17508260808335738, 0.3111521947954433, 0.5211230285003844, 0.3111521947954433, 0.5211230285003846, -0.5089025606249975, -0.08897969566205755, -0.5089025606249975, -0.08897969566205753, -0.785274533858358, 0.2966023384405856, -0.785274533858358, 0.2966023384405857, 0.13643734685972797, -0.5487534801505365, 0.136437346859728, -0.5487534801505362, -0.5113536157192956, -0.38818343681854633, -0.5113536157192953, -0.3881834368185463, 0.6482527388360249, -0.3660801422494009, 0.6482527388360252, -0.3660801422494007, 0.1219550825441264, 0.2636220365395331, 0.12195508254412644, 0.2636220365395332, 0.830646565838305, 0.05595258169938715, 0.8306465658383052, 0.055952581699387154, 0.02087272912166732, -0.2757601788166507, 0.02087272912166733, -0.2757601788166507, -0.8969757534742673, -1.0096320440536182, -0.8969757534742671, -1.0096320440536182, 0.281470556211261, -0.5392051870077439, 0.281470556211261, -0.5392051870077438, 0.09939015666169382, -0.0010699511947921958, 0.09939015666169386, -0.0010699511947921952, -0.002256115172019346, -0.04020319566150099, -0.0022561151720193458, -0.04020319566150097, 0.4504785560293585, 0.373102472756903, 0.4504785560293585, 0.3731024727569031, 0.5231672603524817, 0.16985255790851625, 0.5231672603524821, 0.16985255790851628, -0.7514640400004967, 0.07080018087746165, -0.7514640400004965, 0.07080018087746165, 0.13303832542382837, 0.2602273203264872, 0.1330383254238284, 0.2602273203264874, 0.19343395931079577, -0.5502548672222486, 0.1934339593107958, -0.5502548672222483, -0.20823169078587966, -0.925945416171643, -0.20823169078587964, -0.925945416171643, -1.0354112179615744, 0.9009086420084467, -1.035411217961574, 0.9009086420084467, -0.13833287790394402, 0.33595123313495734, -0.13833287790394397, 0.3359512331349575, -0.48681401106341476, 0.012840401303908289, -0.4868140110634147, 0.012840401303908292, -0.38580806564875847, -0.3414309718415358, -0.3858080656487583, -0.3414309718415357, -0.387387928447792, 0.3363647167396555, -0.387387928447792, 0.3363647167396555, -0.7289577885281368, 0.11000344782305926, -0.7289577885281364, 0.11000344782305929, 0.5996652640170703, -0.3788676471009784, 0.5996652640170704, -0.37886764710097826, 0.1184108904136601, -0.36481788339618465, 0.11841089041366011, -0.36481788339618465, -0.030883796635844396, -0.2470002368704879, -0.030883796635844393, -0.24700023687048783, 0.003754694361758959, -0.19869298401291166, 0.0037546943617589594, -0.1986929840129116, 0.11693502055240339, 0.2098964093295748, 0.11693502055240342, 0.20989640932957487, -0.44372931923544234, 0.056472315155220026, -0.44372931923544234, 0.05647231515522005, -0.2835673309912712, -0.5631986234801009, -0.2835673309912712, -0.5631986234801006, 0.6006827467154858, -0.5932750105917384, 0.6006827467154859, -0.593275010591738, 0.24363277450292076, -0.14517064380485928, 0.24363277450292084, -0.14517064380485925, -0.4381173292277971, 0.8515765445495456, -0.4381173292277971, 0.8515765445495457, -0.4772264554892779, -0.4558040067081244, -0.4772264554892779, -0.4558040067081244, 0.42511520260261526, -0.11760098022868892, 0.4251152026026154, -0.11760098022868892, -0.317536469473846, -0.6047699984659938, -0.31753646947384584, -0.6047699984659937, -0.47946248289928994, -0.6870741625598951, -0.47946248289928994, -0.6870741625598947, 0.24756054302633185, 0.738575212829874, 0.24756054302633188, 0.738575212829874, 0.30991707565082616, -0.1730076242522987, 0.3099170756508263, -0.17300762425229868, 0.1762415438802143, -0.45603299469545666, 0.17624154388021437, -0.4560329946954566, -0.5684090790521096, -0.5323520385817601, -0.5684090790521092, -0.5323520385817597, 1.1773067064626908, -0.31618798230516987, 1.177306706462691, -0.3161879823051697, -0.2853416740347503, -0.7541701445620144, -0.28534167403475025, -0.7541701445620143, -0.3324739283651593, -0.041138670378205386, -0.33247392836515915, -0.041138670378205386, 1.2664180977863824, -0.7401911722318033, 1.2664180977863828, -0.740191172231803, 0.4182693143279388, -0.7039334975576141, 0.41826931432793885, -0.703933497557614, 0.3813359912592416, -1.0453256669790556, 0.3813359912592416, -1.0453256669790554, 0.6509129030314083, -0.5412696201327558, 0.6509129030314084, -0.5412696201327558, 0.12018094767199916, 0.5279211204926886, 0.12018094767199916, 0.5279211204926887, -0.45305717081196895, 0.008198588994697165, -0.45305717081196883, 0.008198588994697166, 1.1671283999119613, -0.15065449704305311, 1.167128399911962, -0.1506544970430531, -0.9008096320814036, 0.1402761647761295, -0.9008096320814036, 0.14027616477612953, -0.33154219658246964, 0.2612070104089204, -0.3315421965824696, 0.2612070104089204, -0.03280139984795011, -0.46647401981355685, -0.032801399847950094, -0.46647401981355685, 0.01502591710973531, -0.5159959791954403, 0.015025917109735313, -0.51599597919544, 0.08126445056757484, -0.059451961687364746, 0.08126445056757486, -0.05945196168736473, -0.4257412994811337, -0.20546840486340784, -0.4257412994811336, -0.20546840486340776, 0.38799639318217627, 0.3512270928822726, 0.3879963931821764, 0.35122709288227266, 0.21154693848150546, -0.03634275654418231, 0.21154693848150552, -0.0363427565441823, -0.23511045964865424, -0.3182820554745927, -0.23511045964865424, -0.3182820554745926, -0.27930734350964126, -0.34019779603069944, -0.27930734350964115, -0.3401977960306993, -0.7191434211894179, 0.018581718879366438, -0.7191434211894179, 0.018581718879366448, -0.020348708221664874, -0.11541476308320475, -0.020348708221664864, -0.11541476308320471, -0.869130537954744, 0.5168791425703672, -0.8691305379547439, 0.5168791425703672, -0.30797478551715907, 0.16894312777393505, -0.30797478551715896, 0.16894312777393514, -0.3412253953512523, -0.13703919671643483, -0.3412253953512523, -0.1370391967164348, -0.2363788997551411, 0.020160959823633195, -0.2363788997551411, 0.020160959823633202, -1.1342573157600304, -1.0490903515949865, -1.1342573157600302, -1.0490903515949863, -0.7951801524174422, -0.39048765852721024, -0.7951801524174421, -0.39048765852721024, -0.37682393173602985, -0.7154876526440125, -0.37682393173602974, -0.7154876526440123, -0.7261698499159233, 0.25576182656428276, -0.7261698499159229, 0.25576182656428287, 0.6047122068958138, 0.3531321759458359, 0.604712206895814, 0.35313217594583596, -0.3347865534686024, -0.44639370766792674, -0.3347865534686024, -0.4463937076679267, -0.3162737402922597, -0.6054254978296343, -0.3162737402922597, -0.6054254978296342, -0.38296113359720985, 1.055727844318872, -0.38296113359720985, 1.0557278443188722, -0.002541168924166004, -0.08959542143473792, -0.0025411689241660036, -0.08959542143473788, -0.46847678028199197, 0.3128229066138286, -0.4684767802819919, 0.3128229066138288, -0.7474510887594696, -0.11273520921655422, -0.7474510887594695, -0.11273520921655422, -0.10138857243233154, 0.6540514477632215, -0.10138857243233154, 0.6540514477632217, 0.7025815823095183, -0.6472293123262207, 0.7025815823095184, -0.6472293123262207, 0.7918249248447928, -0.19424553454596438, 0.7918249248447932, -0.19424553454596438, 0.054665259285737594, -0.1426160884627486, 0.05466525928573761, -0.14261608846274854, 0.8678958225451003, 0.7680573370722297, 0.8678958225451004, 0.7680573370722298, 0.2527320686719843, -0.10300747956510839, 0.25273206867198444, -0.10300747956510836, 0.013030931888632663, 0.2996259196764839, 0.013030931888632665, 0.2996259196764839, 1.2101948699429645, 0.7680276029628541, 1.210194869942965, 0.7680276029628543, 0.001739080834353146, 0.7050842932559666, 0.0017390808343531463, 0.7050842932559666, 0.7920805263720672, -0.5649631474553106, 0.7920805263720672, -0.5649631474553105, 0.25575043599568525, 0.0889317006762374, 0.25575043599568525, 0.08893170067623742, 0.09261316731698108, 0.2703067174076892, 0.0926131673169811, 0.27030671740768925, -0.5747802180771169, 0.08613851106223658, -0.5747802180771168, 0.08613851106223662, 0.40507673833837643, -0.8945358512704514, 0.40507673833837643, -0.8945358512704511, 0.3856111747477545, -0.11976774680260635, 0.3856111747477546, -0.11976774680260632, -0.25578702556512617, 0.3677566511805598, -0.255787025565126, 0.36775665118055983, -0.20976738975410314, 0.6671667928732408, -0.20976738975410314, 0.6671667928732408, -0.21007992057543357, 0.11101431938197523, -0.21007992057543348, 0.11101431938197523, -0.5538419739084758, -0.050566470413442005, -0.5538419739084757, -0.05056647041344199, -0.26983745787555147, -0.005254721629673997, -0.2698374578755514, -0.0052547216296739965, -0.31654388864740896, 0.4356887820490702, -0.3165438886474089, 0.43568878204907036, -0.6124922582532396, -0.22656761299178974, -0.6124922582532395, -0.22656761299178974, 0.5136728866074527, -0.14672923625352396, 0.513672886607453, -0.14672923625352388, -0.06100014188022765, -0.07483055132359873, -0.06100014188022765, -0.07483055132359868, 0.0632389321030824, -0.3727037315430909, 0.06323893210308244, -0.3727037315430909, -0.6239765829480394, -0.43378186506793615, -0.6239765829480394, -0.43378186506793603, -0.2962023614106011, -0.24082492622254642, -0.296202361410601, -0.24082492622254636, -0.08363974045743232, 0.4635673337808054, -0.08363974045743229, 0.4635673337808054, -0.07869730556773968, 0.7594146318238462, -0.07869730556773967, 0.7594146318238463, 0.559161552723403, 0.26005051714491845, 0.5591615527234033, 0.2600505171449186, 0.009099193447173748, -0.8925628969298484, 0.00909919344717375, -0.892562896929848, -0.01551647656911137, -0.38885814801603924, -0.015516476569111365, -0.38885814801603924, -0.01567035614455939, -0.3579485826040038, -0.015670356144559385, -0.35794858260400375, 0.446781462990565, -0.052239411468506664, 0.446781462990565, -0.05223941146850665, 1.0710389841912518, -0.2731132034289364, 1.0710389841912522, -0.2731132034289364, 0.23533790163003582, -0.23476194158747798, 0.23533790163003585, -0.23476194158747793, 0.07915424936926652, 0.6036539628377416, 0.07915424936926652, 0.6036539628377419, 0.6311044368999582, -0.6562564634414947, 0.6311044368999585, -0.6562564634414947, -0.21077148265812098, 0.032523815759867236, -0.2107714826581209, 0.03252381575986725, -0.7231240597670221, -0.006544627251553192, -0.7231240597670221, -0.006544627251553192, -0.08060584759784664, 0.13336777305165762, -0.08060584759784663, 0.13336777305165762, 0.48597827619774187, -0.6069162101181359, 0.48597827619774203, -0.6069162101181359, -0.4507483055292626, 0.19434862886898324, -0.4507483055292625, 0.19434862886898324, 0.2827195867383647, -0.22519487430374507, 0.2827195867383647, -0.22519487430374502, -0.8215093346304647, -0.03268014435976413, -0.8215093346304647, -0.03268014435976413, -0.11933763497114419, 0.25235131805383626, -0.11933763497114419, 0.25235131805383626, -0.050641541900826315, -0.05481336786080909, -0.05064154190082631, -0.05481336786080908, 0.37639163137503584, -0.04913023720926801, 0.37639163137503595, -0.049130237209268006, 0.2754899163868257, -1.2892018379461803, 0.27548991638682585, -1.28920183794618, 0.19113786193208002, -0.49992907513642937, 0.1911378619320801, -0.4999290751364293, -0.18408107881733532, -0.6738283284096425, -0.18408107881733524, -0.6738283284096425, 0.26736586776080096, 0.35645201936711196, 0.2673658677608011, 0.35645201936711196, 1.1765511302564113, -0.5480893596413949, 1.176551130256412, -0.5480893596413949, 1.1542398998705217, -0.3147952918363603, 1.1542398998705217, -0.3147952918363603, -0.6689853024562176, 0.8040377543458188, -0.6689853024562172, 0.804037754345819, 0.24120212235388105, -0.07423471553787372, 0.2412021223538811, -0.0742347155378737, 0.5689391732853385, -0.4334628652354342, 0.5689391732853388, -0.43346286523543415, -0.4229071860412019, 0.11827577249881677, -0.4229071860412019, 0.11827577249881677, -0.5721332694193333, 0.26812444739865027, -0.5721332694193333, 0.26812444739865043, -0.14648803653271852, 0.4305316791577641, -0.1464880365327185, 0.43053167915776425, 0.05374623984152754, -0.4459959249147729, 0.053746239841527564, -0.4459959249147729, 0.5896530144495327, 0.07735649659442079, 0.589653014449533, 0.07735649659442081, -0.25257596915203095, -0.1831343633500895, -0.2525759691520309, -0.18313436335008942, 0.6519199000082152, 0.8113502122689806, 0.6519199000082153, 0.811350212268981, -0.20987680281715365, 0.31018961232143716, -0.2098768028171536, 0.3101896123214372, 0.488852615545995, -0.7694857263920457, 0.488852615545995, -0.7694857263920457, 0.32498664525642773, 0.35466894818618966, 0.3249866452564279, 0.3546689481861898, -0.21867254773101694, 0.33653237135631914, -0.21867254773101685, 0.3365323713563192, -0.1628632057456908, 0.12513912098254698, -0.16286320574569077, 0.12513912098254704, -0.2482127546806861, 0.054592620932045616, -0.24821275468068604, 0.05459262093204564, 0.19972864932719311, 0.48470032915534, 0.19972864932719311, 0.4847003291553401, 0.5194203708908046, 0.6086898891039105, 0.519420370890805, 0.6086898891039109, 0.19766219439600413, -0.624494348335875, 0.1976621943960042, -0.6244943483358748, -0.6659766058933296, 0.5642507949642299, -0.6659766058933294, 0.56425079496423, 0.6380303702196312, 0.7911458327140173, 0.6380303702196312, 0.7911458327140173, -0.2639580944341406, 1.0973674142268384, -0.26395809443414053, 1.0973674142268388, -0.013043068475538544, -0.18048505417693753, -0.013043068475538539, -0.1804850541769375, -0.6177459783187123, -0.2779905668540201, -0.6177459783187123, -0.27799056685401996, 0.6541020344580163, 0.582124792529954, 0.6541020344580166, 0.5821247925299543, -1.0384774049322054, 0.8009193618277922, -1.0384774049322048, 0.8009193618277922, -0.1554306169575903, 0.44885645072316704, -0.15543061695759022, 0.4488564507231671, -0.21901225075291414, 0.029572470395186623, -0.21901225075291408, 0.029572470395186626, 0.06665349581693292, 0.2278463140029154, 0.06665349581693296, 0.22784631400291547, -0.18730209014152358, -0.44204961843797247, -0.1873020901415235, -0.44204961843797247, -0.8954194222707068, -0.09622762051569644, -0.8954194222707068, -0.09622762051569644, 0.6876813467148475, -0.1006745035590906, 0.6876813467148476, -0.10067450355909059, 0.8020144882556199, -0.4557444532553835, 0.80201448825562, -0.4557444532553834, 0.11678579588295551, 0.4778013596576872, 0.11678579588295553, 0.4778013596576872, -0.6173779479953273, -0.1463086195272349, -0.6173779479953271, -0.1463086195272348, 0.04109570275886973, -0.38022576288843984, 0.04109570275886973, -0.3802257628884398, 0.8314003498756972, -0.48166469434786263, 0.8314003498756976, -0.4816646943478625, -0.3417449594665635, 0.2351852756985343, -0.34174495946656336, 0.23518527569853434, -0.747231864230736, -0.05533196936496787, -0.7472318642307357, -0.055331969364967856, 0.44786515872763016, -0.8581662077619436, 0.4478651587276303, -0.8581662077619435, 0.2394196493059546, 0.5685962507505915, 0.23941964930595466, 0.5685962507505915, -0.47370747024486054, -0.518217306207919, -0.4737074702448605, -0.5182173062079186, -0.24686466238928517, 0.5140980999371543, -0.24686466238928517, 0.5140980999371544, 0.4465869335283311, -0.37822156772624715, 0.4465869335283311, -0.378221567726247, 0.7216840280411014, -0.12155234552799939, 0.7216840280411017, -0.12155234552799934, 0.015204864396908546, 0.6376683618342354, 0.015204864396908548, 0.6376683618342357, -0.42393694982300156, -0.5218089477315881, -0.42393694982300145, -0.5218089477315878, 0.07415078821601045, 0.6371956908817733, 0.07415078821601047, 0.6371956908817734, -0.1903574628038755, -0.38684400671343444, -0.19035746280387544, -0.38684400671343444, -0.3773559131237457, 0.0068579608273421355, -0.3773559131237457, 0.006857960827342137, 0.08501466839094085, 0.27421860297639405, 0.08501466839094089, 0.2742186029763941, 1.3703190609240201, -0.6705242349995242, 1.3703190609240201, -0.6705242349995238, 0.22067502222484947, -0.42972719575427676, 0.22067502222484955, -0.4297271957542766, 0.4496324731373458, -0.5997904924904096, 0.44963247313734583, -0.5997904924904094, 0.4606769016215748, -0.4028663766293615, 0.4606769016215748, -0.4028663766293614, 0.20461881450521396, 0.23845839738985905, 0.20461881450521396, 0.2384583973898591, -0.177021903697815, 0.0017472361069717779, -0.17702190369781493, 0.0017472361069717785, 0.33088666738271627, 0.39635242461181414, 0.33088666738271644, 0.39635242461181425, -0.5126793030962896, -0.9816818891160128, -0.5126793030962894, -0.9816818891160127, -0.20315580021343643, 0.25993483522132416, -0.2031558002134364, 0.2599348352213242, 0.01157315314252727, -0.0752286580183012, 0.011573153142527272, -0.07522865801830117, -0.2122874953702656, 1.0455265018271471, -0.2122874953702656, 1.0455265018271478, -0.4118959539781374, 0.2565463745780656, -0.41189595397813733, 0.2565463745780657, -0.40504807761153394, -0.826767279687959, -0.40504807761153383, -0.8267672796879587, 0.8728370056581523, -0.8489146211330629, 0.8728370056581523, -0.8489146211330626, -0.15484731030271964, 0.2978543674333216, -0.15484731030271962, 0.2978543674333217, 0.9598395979151622, -0.021475535817715843, 0.9598395979151622, -0.021475535817715833, -0.3813769756912948, 0.7192828208488169, -0.38137697569129464, 0.719282820848817, 0.21951101473819934, 0.6480843500744788, 0.21951101473819934, 0.6480843500744791, -0.3113427744080721, 0.045948715073330315, -0.31134277440807195, 0.045948715073330336, -0.16009981684527497, -0.17250123317199526, -0.16009981684527497, -0.17250123317199526, 0.25568807750253153, 0.30423782531372767, 0.2556880775025317, 0.30423782531372784, 0.2534978588720535, 0.41258202395216825, 0.25349785887205356, 0.4125820239521684, -0.22823188438717018, 0.3555909158613313, -0.22823188438717018, 0.3555909158613314, -0.043847734475191566, 0.546988883272136, -0.04384773447519155, 0.5469888832721362, 0.0022848127328267687, 0.16581911916150355, 0.0022848127328267695, 0.16581911916150358, -0.9664510167365821, 0.5772556019222926, -0.9664510167365818, 0.5772556019222929, 0.19331577714046103, 0.16819098929912168, 0.1933157771404611, 0.16819098929912168, 0.880938028512706, 1.3996876457175011, 0.8809380285127063, 1.3996876457175018, -0.6403207225525454, 0.2297596920614577, -0.640320722552545, 0.22975969206145774, -0.926993144927124, -0.7404608887419831, -0.9269931449271237, -0.7404608887419828, -0.30368277421537726, -0.5055446699316368, -0.3036827742153772, -0.5055446699316366, 0.5466694604144853, 0.07004761038909013, 0.5466694604144854, 0.07004761038909016, 0.25500851421300097, -0.29367076034138706, 0.25500851421300114, -0.29367076034138695, 0.15138727668563495, -0.0049418965549759275, 0.151387276685635, -0.004941896554975927, -0.43887856303510187, 0.8136477342030863, -0.4388785630351018, 0.8136477342030866, -0.33880265875092413, -0.31551224415527107, -0.33880265875092397, -0.315512244155271, 1.377423681456482, 0.012704561359672462, 1.377423681456482, 0.012704561359672462, -0.041263422421853435, 0.4035844851267748, -0.041263422421853414, 0.40358448512677497, -0.08610165644909173, -0.7986737010728233, -0.08610165644909172, -0.7986737010728232, 0.3836918938530838, 0.8390085156051033, 0.38369189385308383, 0.8390085156051033, -0.17307936456124118, -0.06474709047756155, -0.1730793645612411, -0.06474709047756153, -0.02753475823767776, -0.15870621273858665, -0.02753475823767775, -0.15870621273858657, -0.5116996522331295, -0.4553457116638264, -0.5116996522331294, -0.45534571166382637, 0.6086269804673172, 0.015815755110900165, 0.6086269804673176, 0.015815755110900165, -0.3066696359213093, -0.6490796718967194, -0.3066696359213093, -0.6490796718967194, 0.2573582808012723, 0.49429943061451787, 0.25735828080127243, 0.4942994306145179, -0.5573569025227104, 0.10864971359925568, -0.5573569025227101, 0.1086497135992557, 0.10100854569812368, -0.5775400700305715, 0.10100854569812368, -0.5775400700305712, 0.16011849083924728, -0.5182501761924749, 0.1601184908392473, -0.5182501761924749, 1.1626364195660153, -0.027141868869618918, 1.162636419566016, -0.027141868869618915, -0.45286020053725284, 0.46618578082394724, -0.4528602005372528, 0.4661857808239473, 0.32258327609642495, -0.2102016160014837, 0.3225832760964251, -0.21020161600148368, -0.4469041249092892, -0.30385833257152894, -0.4469041249092891, -0.30385833257152894, 0.8377224062973287, -0.5225876068528582, 0.8377224062973289, -0.5225876068528581, -0.35063350958529577, -0.44521824304962737, -0.3506335095852957, -0.44521824304962726, 0.042917945172412694, -0.2699072536318396, 0.0429179451724127, -0.2699072536318395, 0.28617439894992625, -0.6241441143108587, 0.28617439894992625, -0.6241441143108584, -0.21331655993940007, 1.1315954154549954, -0.21331655993940002, 1.1315954154549959, -0.7071603986591413, -0.0587365030909921, -0.7071603986591409, -0.0587365030909921, -0.43104678259786616, -0.4031905103539523, -0.4310467825978661, -0.40319051035395215, 0.479647329346727, -0.6208557999362405, 0.47964732934672716, -0.6208557999362404, -0.27104983788326825, 0.005338803231299233, -0.2710498378832682, 0.0053388032312992354, -0.0041329173810210895, 0.3935166528530436, -0.004132917381021089, 0.39351665285304366 }; + std::vector coords2 = {{0.22627000864084901,-0.54844786814738589},{0.22627000864084906,-0.54844786814738566},{0.76619269852077698,-0.061145602795363019},{0.76619269852077709,-0.061145602795363019},{0.40151121510492016,0.086169795574700322},{0.40151121510492027,0.086169795574700336},{-0.41675996433129736,-0.59027874913058564},{-0.41675996433129719,-0.59027874913058531},{-0.2479064469635639,-0.74720116474978726},{-0.24790644696356384,-0.74720116474978715},{0.60789884816898987,-0.80871902661746131},{0.60789884816899009,-0.80871902661746098},{0.68442386819866474,-0.22229148851718702},{0.68442386819866474,-0.222291488517187},{0.64868329411814507,0.37061949503943492},{0.64868329411814518,0.37061949503943492},{-0.53610488421312485,-0.16765691382574804},{-0.53610488421312452,-0.16765691382574799},{0.45883589867372032,-0.90002805519775253},{0.45883589867372049,-0.90002805519775253},{0.39606519269386431,0.19117525930527385},{0.39606519269386437,0.1911752593052739},{0.30699987842448867,-0.40671559965800569},{0.30699987842448873,-0.40671559965800558},{0.47811583559881354,0.45514850809555862},{0.47811583559881354,0.45514850809555862},{0.55694942027704353,0.31742754487478431},{0.55694942027704386,0.31742754487478447},{-0.42770276051753919,0.096955878665120218},{-0.42770276051753908,0.096955878665120246},{-0.57481148072658073,-0.038382186575755678},{-0.57481148072658061,-0.038382186575755671},{-1.0317070883952917,-0.52452560324702835},{-1.031707088395291,-0.52452560324702835},{0.14712374452633492,0.33141471681448986},{0.147123744526335,0.33141471681448986},{-0.28347372190042908,-0.92715879841205417},{-0.28347372190042891,-0.92715879841205384},{-0.60981494869467312,0.55537737258362951},{-0.6098149486946729,0.55537737258362951},{1.1206314478250745,0.3921423623286639},{1.1206314478250745,0.39214236232866406},{0.44775389736658761,-0.04256704865570235},{0.44775389736658772,-0.04256704865570235},{-0.61566353088890424,-0.10817302193016937},{-0.61566353088890413,-0.10817302193016932},{0.17897362794557034,-0.042242278527696159},{0.17897362794557034,-0.042242278527696138},{-0.96468857898503324,-1.4563419829050452},{-0.96468857898503313,-1.456341982905045},{0.29116134151602552,0.015655417967490592},{0.29116134151602563,0.015655417967490596},{-0.36989185408319708,0.6983267205999204},{-0.36989185408319691,0.69832672059992051},{1.4056553730213062,-0.41615789580202767},{1.4056553730213066,-0.41615789580202767},{0.34141990921721344,-0.56795515029886612},{0.3414199092172136,-0.56795515029886612},{0.29573181376693408,0.84164996015350579},{0.29573181376693425,0.84164996015350602},{0.035141462612931273,-0.45835970615650135},{0.035141462612931287,-0.45835970615650123},{-1.3263110033694971,0.82232903519083456},{-1.3263110033694969,0.82232903519083456},{-0.18787969354847422,1.4601214758378256},{-0.18787969354847417,1.4601214758378258},{-0.54216845907429567,-0.51961180800381568},{-0.54216845907429556,-0.51961180800381568},{-0.15415956428809274,0.25532654830928558},{-0.15415956428809266,0.25532654830928564},{0.24744639466303925,0.36561549310806263},{0.24744639466303933,0.36561549310806274},{-0.0079492255222306241,-0.44633135701879739},{-0.0079492255222306206,-0.44633135701879723},{0.43142827498651759,0.69071652446837439},{0.4314282749865177,0.69071652446837439},{0.22721916356346672,-1.1459249857200779},{0.22721916356346675,-1.1459249857200775},{0.11627266697915434,0.56795849774853857},{0.11627266697915438,0.5679584977485389},{-0.0047602418548348679,1.341758406463988},{-0.0047602418548348662,1.3417584064639887},{0.34070213758085,-0.45244469345136928},{0.34070213758085011,-0.45244469345136923},{0.88428750905930542,-0.43693290590949829},{0.88428750905930553,-0.43693290590949824},{0.1514286184534766,-0.17725085421066233},{0.15142861845347666,-0.17725085421066225},{-0.42552588120899021,-0.48986352859695054},{-0.42552588120899015,-0.48986352859695048},{0.93772614827627832,-0.14434813485483561},{0.93772614827627843,-0.14434813485483552},{0.042603455038522919,0.95137704586754301},{0.042603455038522919,0.95137704586754301},{0.30524358401360402,-0.38754726292661379},{0.30524358401360402,-0.38754726292661379},{0.036037559408935993,0.34504467425927055},{0.036037559408936,0.34504467425927055},{0.74328695223297925,-0.7836440067269177},{0.74328695223297947,-0.78364400672691747},{-0.29639573830543459,-0.8541077824286829},{-0.29639573830543442,-0.8541077824286829},{-0.59577747904802425,-0.60070971234972603},{-0.59577747904802414,-0.60070971234972581},{-0.16224562470708315,0.34537414926581733},{-0.16224562470708306,0.34537414926581733},{-0.74246621633674525,-0.41130625924230096},{-0.74246621633674503,-0.41130625924230085},{-0.36245903965310422,-0.10563984421746442},{-0.36245903965310411,-0.10563984421746442},{-0.53929041105603615,-0.085181852594290175},{-0.53929041105603581,-0.085181852594290161},{-0.6778672159722301,0.34316734490698553},{-0.6778672159722301,0.34316734490698558},{0.36715717958832705,-0.59107287610897663},{0.36715717958832716,-0.59107287610897641},{-0.025023155416355747,0.049551540818041445},{-0.025023155416355747,0.049551540818041459},{-0.24819669042158904,1.5510767274238919},{-0.24819669042158898,1.5510767274238921},{0.56719315766279499,0.11906741314152564},{0.56719315766279499,0.11906741314152564},{-0.040143445247768667,0.26972252794743534},{-0.04014344524776866,0.26972252794743534},{-0.2625294670890006,-0.98663935013810755},{-0.26252946708900049,-0.98663935013810733},{0.44843907219373064,0.80480817549220252},{0.44843907219373064,0.80480817549220274},{0.064560053758703106,1.0817638655728792},{0.064560053758703134,1.0817638655728798},{0.76754320881104166,-0.88127171146103123},{0.76754320881104166,-0.88127171146103089},{-0.082864942688970003,-0.4289421536808215},{-0.082864942688969975,-0.42894215368082134},{-0.41612370586918423,0.48867158558340018},{-0.41612370586918423,0.48867158558340035},{0.19771717248920714,-0.1094932114101852},{0.19771717248920723,-0.10949321141018517},{0.33257437704357651,0.30500596066144547},{0.33257437704357662,0.30500596066144559},{-0.60766757508855918,-0.24888805715678461},{-0.60766757508855884,-0.24888805715678455},{-0.13216710101702264,-0.50664738755023464},{-0.13216710101702256,-0.50664738755023453},{0.8513876721292416,-0.54892416093653573},{0.8513876721292416,-0.54892416093653562},{-0.38228917502613802,-0.47285448091622573},{-0.38228917502613796,-0.47285448091622562},{-0.22454842691828375,0.61513791126500528},{-0.22454842691828367,0.61513791126500561},{-0.86460141755362863,-0.42386569643498184},{-0.8646014175536284,-0.42386569643498179},{0.31173162263869658,0.26276133574181793},{0.31173162263869669,0.26276133574181798},{-0.15249103914387663,0.43953796133154421},{-0.15249103914387657,0.43953796133154432},{-0.85353039485907578,-0.51711368923164358},{-0.85353039485907556,-0.51711368923164347},{0.55489084997054272,0.75054716212605976},{0.55489084997054272,0.7505471621260601},{-0.060511331387651107,0.10241755750407933},{-0.0605113313876511,0.10241755750407933},{0.53372884232138706,-0.4674709006951539},{0.53372884232138729,-0.4674709006951539},{0.054327267054586861,0.74042400433618216},{0.054327267054586875,0.74042400433618238},{0.18755513858332273,-0.33846461008241124},{0.18755513858332279,-0.33846461008241124},{-0.85911702424429581,0.10096092456106642},{-0.85911702424429559,0.10096092456106642},{-0.6532878500824677,0.06191743854152687},{-0.65328785008246748,0.06191743854152687},{-0.85396145872153717,-0.73248240099624018},{-0.85396145872153717,-0.73248240099624018},{-0.58638026679645594,-1.0565461549299311},{-0.58638026679645561,-1.0565461549299304},{-0.17904691663055011,0.2959320232236789},{-0.17904691663055006,0.2959320232236789},{-0.1360834565364501,-0.11972427421383847},{-0.13608345653645007,-0.11972427421383845},{1.0002796523084041,0.56778407120105678},{1.0002796523084043,0.56778407120105678},{-0.25394170147348538,-0.24824262411661902},{-0.25394170147348533,-0.24824262411661896},{-0.55133142102369248,0.164455936053998},{-0.55133142102369215,0.16445593605399808},{-0.35669084505120763,-0.55793659951732932},{-0.35669084505120757,-0.55793659951732899},{-0.00479028693868494,0.57479595976998255},{-0.0047902869386849392,0.57479595976998288},{0.92746188573367616,0.3137388167061812},{0.92746188573367649,0.31373881670618131},{-0.15826544626455591,0.085322444035693779},{-0.15826544626455591,0.08532244403569382},{-0.7338606250043278,0.038845365230724127},{-0.7338606250043278,0.038845365230724134},{0.44163054667470403,-0.47579789982679749},{0.44163054667470419,-0.47579789982679749},{-0.34063918884986699,-0.016461235375619054},{-0.34063918884986699,-0.016461235375619051},{0.6944973204450795,-0.051270490770679578},{0.69449732044507984,-0.051270490770679564},{0.056921957646351592,-0.48602348989133548},{0.056921957646351613,-0.48602348989133548},{-0.34909544551668503,0.07925987763994416},{-0.34909544551668492,0.07925987763994416},{0.020842670418798892,-0.18962128485770935},{0.020842670418798902,-0.18962128485770929},{-0.24296262993119017,-0.75570624366243377},{-0.24296262993119008,-0.75570624366243344},{0.077677850365247728,-0.075674513837619806},{0.077677850365247741,-0.075674513837619806},{-0.53835871249354228,0.31499084023358759},{-0.53835871249354195,0.31499084023358759},{-0.36725475571305921,0.84973522821457648},{-0.36725475571305921,0.84973522821457681},{1.0306858576839981,0.61321701008481488},{1.0306858576839986,0.61321701008481522},{0.026403641820751278,-0.11123958700346126},{0.026403641820751288,-0.11123958700346125},{-0.39673068933170313,0.73652102123805863},{-0.39673068933170308,0.73652102123805863},{-0.27385911073904101,0.15083421880672626},{-0.2738591107390409,0.15083421880672626},{-0.75025035911181925,-0.62737504253230147},{-0.75025035911181914,-0.62737504253230136},{1.040458273889268,0.35921626394454131},{1.0404582738892683,0.35921626394454143},{-0.30951481303178596,-0.79901979756841535},{-0.30951481303178585,-0.79901979756841524},{-0.30498616678906948,1.6737307580052914},{-0.30498616678906937,1.673730758005292},{0.60193547529774705,1.1660575124169412},{0.60193547529774705,1.1660575124169419},{0.88389923708380991,0.26564156360743529},{0.88389923708381024,0.26564156360743529},{-0.50857272480685156,-0.23584500534815295},{-0.50857272480685145,-0.23584500534815289},{0.53962173286377091,-0.39810497658583466},{0.53962173286377124,-0.39810497658583466},{0.86654948412408417,0.11624211166929022},{0.86654948412408428,0.11624211166929023},{-0.51942267345287996,0.53952242354399216},{-0.51942267345287962,0.53952242354399216},{0.19088288221197763,-0.46633362159701208},{0.19088288221197763,-0.46633362159701192},{-0.23194847381262582,0.21901474700861162},{-0.23194847381262573,0.21901474700861162},{0.83594364023693446,-0.26797796507308069},{0.83594364023693457,-0.26797796507308053},{0.4468309121482219,0.72473851177019499},{0.4468309121482219,0.72473851177019533},{0.59637916844575234,0.87460797379150035},{0.59637916844575245,0.87460797379150068},{-0.16268657840268694,-0.10458689278692812},{-0.16268657840268685,-0.10458689278692809},{0.15167543844454376,0.38106333954930449},{0.15167543844454379,0.3810633395493046},{0.31750471493309029,-0.46806591390997349},{0.31750471493309046,-0.46806591390997349},{0.24518019737678892,0.14105859064554405},{0.24518019737678892,0.1410585906455441},{0.1337014618382204,0.21605338431976101},{0.13370146183822049,0.21605338431976104},{-0.5196743788563577,-0.24381508621133063},{-0.5196743788563577,-0.24381508621133063},{0.16145768845022127,-0.18548235309792105},{0.16145768845022135,-0.18548235309792097},{0.52679560224727773,-0.078068178317287185},{0.52679560224727773,-0.078068178317287157},{0.26905288016629048,0.0077754440561353388},{0.26905288016629048,0.0077754440561353397},{0.75658211608198589,-0.30477492785453741},{0.75658211608198589,-0.30477492785453736},{-0.70164676253539282,0.044709597007475121},{-0.70164676253539249,0.044709597007475142},{0.24152393076611661,0.29722381981294532},{0.24152393076611664,0.29722381981294532},{0.22845920081505419,-0.66082450273667115},{0.22845920081505419,-0.66082450273667115},{0.2123088556780684,0.017821617395191419},{0.21230885567806848,0.017821617395191426},{-0.14619514581307758,-0.88332384590800839},{-0.14619514581307758,-0.88332384590800817},{0.1989466009909055,-0.61184022410822936},{0.1989466009909055,-0.61184022410822914},{0.49059993119084305,-0.16493514201871323},{0.49059993119084311,-0.1649351420187132},{-0.41296483725060629,-0.05944366961592451},{-0.41296483725060618,-0.059443669615924496},{0.58648569289332897,0.32711859709117741},{0.58648569289332919,0.32711859709117747},{-0.060232279111614079,-0.71078428751574663},{-0.060232279111614072,-0.71078428751574663},{0.63103590792494557,0.29992699270395096},{0.63103590792494557,0.29992699270395107},{-0.67030893009865233,0.61074709417056894},{-0.670308930098652,0.61074709417056894},{0.50059572821337772,0.01407262429060302},{0.50059572821337806,0.014072624290603021},{-0.18934890988546538,-0.93727800703183939},{-0.18934890988546529,-0.93727800703183939},{-0.28630871262845642,-0.40444718862380247},{-0.28630871262845636,-0.4044471886238023},{1.190084782443751,0.5322874598725964},{1.1900847824437517,0.53228745987259674},{0.13414429163933239,-0.84206261966612916},{0.13414429163933247,-0.84206261966612894},{-0.76498610844273451,-0.70710735740415742},{-0.7649861084427344,-0.70710735740415731},{-0.36288146348239197,0.4530261596665785},{-0.36288146348239192,0.45302615966657866},{0.13437240869925704,0.076322184873111099},{0.13437240869925712,0.076322184873111099},{1.0481657649638807,-0.0042571858330335832},{1.0481657649638814,-0.0042571858330335806},{-0.74749488152458232,-0.97868443586596532},{-0.74749488152458232,-0.97868443586596532},{0.12735871993303205,-0.31855483679712288},{0.12735871993303208,-0.31855483679712276},{0.36855220211614997,-0.55881232393476865},{0.36855220211615003,-0.55881232393476854},{-0.18314335566244416,-0.54422501797347922},{-0.18314335566244408,-0.544225017973479},{0.08693873231351551,-0.64472862946987664},{0.08693873231351551,-0.64472862946987664},{-0.054814363740555372,0.20956141264894845},{-0.054814363740555372,0.20956141264894851},{-0.27114580055426557,0.12928945128646963},{-0.27114580055426551,0.12928945128646968},{-0.44517604746926243,0.46862844610576626},{-0.44517604746926231,0.46862844610576632},{0.13417308041193721,-0.50794946121864581},{0.13417308041193723,-0.50794946121864559},{0.32574400256966463,0.41535071715298272},{0.32574400256966468,0.41535071715298272},{-1.2231311278955395,0.57049285599372657},{-1.223131127895539,0.5704928559937269},{-0.07375248343426033,-0.55247593176850629},{-0.073752483434260302,-0.55247593176850629},{-0.64133830124419644,-0.3892879515624541},{-0.64133830124419633,-0.38928795156245405},{-0.00088418235809503698,-0.0031857205961429921},{-0.00088418235809503676,-0.0031857205961429908},{0.73756680363736504,-0.76150404463536636},{0.73756680363736538,-0.76150404463536603},{0.23446047289831606,0.19035505393365781},{0.23446047289831606,0.19035505393365784},{-0.072119883773904686,-0.13169854040950443},{-0.072119883773904686,-0.13169854040950443},{0.18143877838398617,1.1320138602932679},{0.18143877838398625,1.1320138602932683},{-0.22066292105815377,-0.19117568196580417},{-0.22066292105815372,-0.19117568196580417},{-0.43474530280543311,0.5888401578252912},{-0.43474530280543294,0.58884015782529153},{0.24005504098930414,0.80214419382049851},{0.24005504098930416,0.80214419382049862},{-0.34929799898447755,-0.26177579765885101},{-0.34929799898447744,-0.26177579765885084},{0.34900776680595957,-0.0077523378139725541},{0.34900776680595968,-0.0077523378139725515},{-0.60257880681375875,0.46068756636034236},{-0.60257880681375853,0.46068756636034242},{-0.71223337128918518,0.26308462754739115},{-0.71223337128918518,0.26308462754739115},{0.15764425398809745,0.18964163728856187},{0.15764425398809748,0.18964163728856193},{0.18537871740218731,-0.67890402091346247},{0.18537871740218737,-0.67890402091346214},{0.63491145339033395,0.13339968677329644},{0.63491145339033428,0.13339968677329647},{-1.2578415170869763,0.2517963788258869},{-1.2578415170869757,0.2517963788258869},{0.14008455938464781,0.40593141307431857},{0.14008455938464787,0.40593141307431863},{-0.70954857255129022,0.82252332056429023},{-0.70954857255128989,0.82252332056429034},{-1.1960848307098382,0.17404679607890605},{-1.196084830709838,0.17404679607890608},{0.21828979413603433,-0.32802648489465958},{0.21828979413603439,-0.32802648489465952},{0.2662387358530971,0.35689296238290469},{0.26623873585309726,0.3568929623829048},{0.24305026107578037,-0.23724020319018074},{0.24305026107578043,-0.23724020319018066},{-0.34338326276503423,0.33894177197700609},{-0.34338326276503406,0.33894177197700609},{-0.043726990434355101,0.58694954546593914},{-0.04372699043435508,0.58694954546593925},{-0.12109570623011018,-0.87728348031605419},{-0.12109570623011016,-0.87728348031605419},{0.096312181234714522,-0.12108887934946555},{0.096312181234714564,-0.12108887934946555},{-0.41811390046020547,0.84650926395392168},{-0.4181139004602053,0.84650926395392179},{-0.34396631561394114,0.83589047976787589},{-0.34396631561394098,0.83589047976787589},{0.43085589801084057,-0.16054297058369527},{0.43085589801084062,-0.16054297058369521},{-0.19787245165430847,0.8949780141072381},{-0.19787245165430842,0.8949780141072381},{-0.59078601004545783,0.18974221311023962},{-0.5907860100454575,0.18974221311023964},{-0.53066913420208861,-0.72750538427098987},{-0.53066913420208861,-0.72750538427098987},{-0.345074608245379,1.2075893215192861},{-0.34507460824537883,1.2075893215192861},{-0.32302823411726667,0.082502525114370479},{-0.32302823411726667,0.082502525114370506},{-0.1000939664088763,-1.056428113867832},{-0.10009396640887627,-1.056428113867832},{0.0057223538613018765,-0.079978011496922158},{0.0057223538613018782,-0.079978011496922158},{-1.0232923766303312,0.22905472765407248},{-1.0232923766303312,0.22905472765407253},{-0.040717874296367529,0.038399041617570462},{-0.040717874296367508,0.038399041617570469},{-0.51146148234315059,-0.067343985087925606},{-0.51146148234315025,-0.067343985087925592},{-0.033395285925899576,-0.25197193535594753},{-0.033395285925899569,-0.25197193535594747},{-1.3238866550876203,-0.34335648499193994},{-1.3238866550876196,-0.34335648499193983},{0.30989498096217988,-0.69255855440631198},{0.30989498096217999,-0.69255855440631187},{-0.77781729696508051,-0.72517256965044208},{-0.7778172969650804,-0.72517256965044208},{0.58324675209929833,-0.00055859793754636788},{0.58324675209929833,-0.00055859793754636767},{0.64027174305363366,-0.24460516745019825},{0.64027174305363366,-0.24460516745019825},{0.3744231501345624,0.23752933224278633},{0.37442315013456257,0.23752933224278638},{-0.55265345991070014,0.2959174882702319},{-0.55265345991069992,0.29591748827023195},{0.087098070970346303,0.011155933053077993},{0.087098070970346317,0.011155933053077997},{0.10294466025799387,0.62462791553584829},{0.10294466025799387,0.6246279155358484},{0.7907530514131953,0.79681309449661364},{0.79075305141319552,0.79681309449661397},{-0.06771348768905705,-0.19742894579933645},{-0.067713487689057036,-0.19742894579933642},{1.7336246702438183,-0.081113697281863462},{1.7336246702438185,-0.081113697281863434},{0.39279504341227045,-0.28034281864931948},{0.39279504341227056,-0.28034281864931943},{-0.38379901873350331,0.58174659960452924},{-0.38379901873350314,0.58174659960452924},{-0.15897299229161954,0.2123178635236439},{-0.15897299229161949,0.21231786352364398},{1.2871753315186103,-0.29365467064853268},{1.2871753315186105,-0.29365467064853262},{-0.28157817609809926,0.015215204873323618},{-0.28157817609809926,0.015215204873323621},{-0.84077857710585868,0.11715953275528568},{-0.84077857710585835,0.11715953275528568},{0.057427665729494065,0.17741033446395021},{0.057427665729494086,0.17741033446395027},{-0.39193335349149089,-0.87770630997796228},{-0.39193335349149089,-0.87770630997796228},{1.0460627590374469,0.12566529633175702},{1.0460627590374476,0.1256652963317571},{0.052082824898560393,0.23074154552008772},{0.052082824898560393,0.23074154552008772},{0.30900939912174769,-0.28949051651550656},{0.3090093991217478,-0.2894905165155065},{-0.90399207988819497,-0.089680289135275371},{-0.90399207988819497,-0.089680289135275371},{0.1114034542194284,-0.14200554909523541},{0.11140345421942845,-0.14200554909523541},{0.49928483909803145,-1.0318604013037751},{0.49928483909803145,-1.0318604013037751},{-0.25021332122685536,-0.23430348924020267},{-0.2502133212268553,-0.23430348924020258},{0.45788605189844944,0.008986832993373578},{0.45788605189844944,0.0089868329933735832},{0.99229861438181677,-0.3970601247358978},{0.9922986143818171,-0.3970601247358978},{0.32422473992995421,0.0088359200544578798},{0.32422473992995421,0.0088359200544578815},{0.61047483911497225,-0.15883704961874789},{0.61047483911497225,-0.15883704961874784},{-0.2328772934092499,-0.28654852459626834},{-0.23287729340924987,-0.28654852459626823},{0.25915793265886788,-0.48250620169929226},{0.25915793265886788,-0.4825062016992922},{0.030769057057074042,-0.66779021826951945},{0.030769057057074042,-0.66779021826951923},{0.5724668628416123,0.17684659209108886},{0.57246686284161241,0.17684659209108886},{-0.1936816938025718,0.017884183939394893},{-0.19368169380257177,0.017884183939394897},{0.39274249467277711,-0.35893202407982278},{0.39274249467277728,-0.35893202407982266},{-0.13217719866296695,0.45090725779207141},{-0.13217719866296687,0.45090725779207153},{0.77712009896984346,0.070940004923181088},{0.7771200989698438,0.070940004923181116},{-0.043208921594939775,-0.70580148507958684},{-0.043208921594939755,-0.70580148507958651},{-0.44161734737621083,0.17508260808335738},{-0.44161734737621083,0.17508260808335738},{0.31115219479544332,0.52112302850038439},{0.31115219479544332,0.52112302850038461},{-0.5089025606249975,-0.088979695662057545},{-0.5089025606249975,-0.088979695662057531},{-0.78527453385835799,0.29660233844058559},{-0.78527453385835799,0.2966023384405857},{0.13643734685972797,-0.54875348015053649},{0.136437346859728,-0.54875348015053615},{-0.51135361571929561,-0.38818343681854633},{-0.51135361571929527,-0.38818343681854628},{0.64825273883602486,-0.36608014224940089},{0.64825273883602519,-0.36608014224940072},{0.1219550825441264,0.26362203653953309},{0.12195508254412644,0.2636220365395332},{0.83064656583830498,0.055952581699387147},{0.83064656583830521,0.055952581699387154},{0.020872729121667322,-0.27576017881665071},{0.020872729121667329,-0.27576017881665071},{-0.89697575347426728,-1.0096320440536182},{-0.89697575347426706,-1.0096320440536182},{0.28147055621126099,-0.53920518700774389},{0.28147055621126099,-0.53920518700774378},{0.099390156661693818,-0.0010699511947921958},{0.09939015666169386,-0.0010699511947921952},{-0.0022561151720193462,-0.04020319566150099},{-0.0022561151720193458,-0.040203195661500969},{0.45047855602935849,0.373102472756903},{0.45047855602935849,0.37310247275690311},{0.52316726035248173,0.16985255790851625},{0.52316726035248207,0.16985255790851628},{-0.75146404000049671,0.070800180877461649},{-0.75146404000049649,0.070800180877461649},{0.13303832542382837,0.26022732032648721},{0.1330383254238284,0.26022732032648738},{0.19343395931079577,-0.55025486722224859},{0.19343395931079579,-0.55025486722224826},{-0.20823169078587966,-0.92594541617164305},{-0.20823169078587964,-0.92594541617164305},{-1.0354112179615744,0.90090864200844667},{-1.035411217961574,0.90090864200844667},{-0.13833287790394402,0.33595123313495734},{-0.13833287790394397,0.33595123313495751},{-0.48681401106341476,0.012840401303908289},{-0.48681401106341471,0.012840401303908292},{-0.38580806564875847,-0.34143097184153581},{-0.3858080656487583,-0.3414309718415357},{-0.38738792844779202,0.33636471673965551},{-0.38738792844779202,0.33636471673965551},{-0.72895778852813675,0.11000344782305926},{-0.72895778852813642,0.11000344782305929},{0.59966526401707032,-0.37886764710097842},{0.59966526401707043,-0.37886764710097826},{0.1184108904136601,-0.36481788339618465},{0.11841089041366011,-0.36481788339618465},{-0.030883796635844396,-0.24700023687048789},{-0.030883796635844393,-0.24700023687048783},{0.003754694361758959,-0.19869298401291166},{0.0037546943617589594,-0.19869298401291161},{0.11693502055240339,0.20989640932957479},{0.11693502055240342,0.20989640932957487},{-0.44372931923544234,0.056472315155220026},{-0.44372931923544234,0.056472315155220047},{-0.28356733099127118,-0.56319862348010086},{-0.28356733099127118,-0.56319862348010064},{0.60068274671548583,-0.59327501059173837},{0.60068274671548594,-0.59327501059173804},{0.24363277450292076,-0.14517064380485928},{0.24363277450292084,-0.14517064380485925},{-0.43811732922779711,0.85157654454954557},{-0.43811732922779711,0.85157654454954568},{-0.47722645548927789,-0.45580400670812438},{-0.47722645548927789,-0.45580400670812438},{0.42511520260261526,-0.11760098022868892},{0.42511520260261543,-0.11760098022868892},{-0.31753646947384601,-0.60476999846599377},{-0.31753646947384584,-0.60476999846599366},{-0.47946248289928994,-0.68707416255989506},{-0.47946248289928994,-0.68707416255989473},{0.24756054302633185,0.73857521282987404},{0.24756054302633188,0.73857521282987404},{0.30991707565082616,-0.17300762425229871},{0.30991707565082632,-0.17300762425229868},{0.17624154388021429,-0.45603299469545666},{0.17624154388021437,-0.45603299469545661},{-0.56840907905210958,-0.53235203858176006},{-0.56840907905210925,-0.53235203858175972},{1.1773067064626908,-0.31618798230516987},{1.177306706462691,-0.3161879823051697},{-0.2853416740347503,-0.75417014456201437},{-0.28534167403475025,-0.75417014456201426},{-0.33247392836515932,-0.041138670378205386},{-0.33247392836515915,-0.041138670378205386},{1.2664180977863824,-0.74019117223180331},{1.2664180977863828,-0.74019117223180297},{0.41826931432793879,-0.70393349755761414},{0.41826931432793885,-0.70393349755761403},{0.38133599125924161,-1.0453256669790556},{0.38133599125924161,-1.0453256669790554},{0.65091290303140825,-0.54126962013275581},{0.65091290303140836,-0.54126962013275581},{0.12018094767199916,0.52792112049268858},{0.12018094767199916,0.52792112049268869},{-0.45305717081196895,0.0081985889946971646},{-0.45305717081196883,0.0081985889946971664},{1.1671283999119613,-0.15065449704305311},{1.1671283999119619,-0.15065449704305309},{-0.90080963208140363,0.1402761647761295},{-0.90080963208140363,0.14027616477612953},{-0.33154219658246964,0.26120701040892041},{-0.33154219658246958,0.26120701040892041},{-0.032801399847950108,-0.46647401981355685},{-0.032801399847950094,-0.46647401981355685},{0.015025917109735311,-0.51599597919544027},{0.015025917109735313,-0.51599597919544005},{0.081264450567574836,-0.059451961687364746},{0.081264450567574864,-0.059451961687364732},{-0.42574129948113371,-0.20546840486340784},{-0.42574129948113359,-0.20546840486340776},{0.38799639318217627,0.35122709288227261},{0.38799639318217638,0.35122709288227266},{0.21154693848150546,-0.036342756544182307},{0.21154693848150552,-0.0363427565441823},{-0.23511045964865424,-0.31828205547459271},{-0.23511045964865424,-0.3182820554745926},{-0.27930734350964126,-0.34019779603069944},{-0.27930734350964115,-0.34019779603069927},{-0.71914342118941788,0.018581718879366438},{-0.71914342118941788,0.018581718879366448},{-0.020348708221664874,-0.11541476308320475},{-0.020348708221664864,-0.11541476308320471},{-0.86913053795474404,0.51687914257036716},{-0.86913053795474393,0.51687914257036716},{-0.30797478551715907,0.16894312777393505},{-0.30797478551715896,0.16894312777393514},{-0.34122539535125229,-0.13703919671643483},{-0.34122539535125229,-0.1370391967164348},{-0.23637889975514109,0.020160959823633195},{-0.23637889975514109,0.020160959823633202},{-1.1342573157600304,-1.0490903515949865},{-1.1342573157600302,-1.0490903515949863},{-0.79518015241744222,-0.39048765852721024},{-0.79518015241744211,-0.39048765852721024},{-0.37682393173602985,-0.71548765264401248},{-0.37682393173602974,-0.71548765264401226},{-0.72616984991592326,0.25576182656428276},{-0.72616984991592293,0.25576182656428287},{0.60471220689581384,0.3531321759458359},{0.60471220689581395,0.35313217594583596},{-0.33478655346860242,-0.44639370766792674},{-0.33478655346860242,-0.44639370766792669},{-0.31627374029225969,-0.60542549782963428},{-0.31627374029225969,-0.60542549782963417},{-0.38296113359720985,1.055727844318872},{-0.38296113359720985,1.0557278443188722},{-0.002541168924166004,-0.089595421434737921},{-0.0025411689241660036,-0.089595421434737879},{-0.46847678028199197,0.31282290661382861},{-0.46847678028199191,0.31282290661382878},{-0.74745108875946964,-0.11273520921655422},{-0.74745108875946953,-0.11273520921655422},{-0.10138857243233154,0.65405144776322155},{-0.10138857243233154,0.65405144776322166},{0.70258158230951828,-0.64722931232622072},{0.70258158230951839,-0.64722931232622072},{0.79182492484479283,-0.19424553454596438},{0.79182492484479317,-0.19424553454596438},{0.054665259285737594,-0.14261608846274859},{0.054665259285737608,-0.14261608846274854},{0.86789582254510034,0.76805733707222967},{0.86789582254510045,0.76805733707222978},{0.25273206867198428,-0.10300747956510839},{0.25273206867198444,-0.10300747956510836},{0.013030931888632663,0.29962591967648389},{0.013030931888632665,0.29962591967648389},{1.2101948699429645,0.76802760296285411},{1.210194869942965,0.76802760296285433},{0.0017390808343531461,0.70508429325596655},{0.0017390808343531463,0.70508429325596655},{0.79208052637206716,-0.56496314745531062},{0.79208052637206716,-0.56496314745531051},{0.25575043599568525,0.088931700676237402},{0.25575043599568525,0.088931700676237416},{0.092613167316981077,0.27030671740768919},{0.092613167316981104,0.27030671740768925},{-0.57478021807711688,0.086138511062236578},{-0.57478021807711677,0.08613851106223662},{0.40507673833837643,-0.89453585127045143},{0.40507673833837643,-0.8945358512704511},{0.38561117474775453,-0.11976774680260635},{0.38561117474775458,-0.11976774680260632},{-0.25578702556512617,0.36775665118055978},{-0.255787025565126,0.36775665118055983},{-0.20976738975410314,0.66716679287324077},{-0.20976738975410314,0.66716679287324077},{-0.21007992057543357,0.11101431938197523},{-0.21007992057543348,0.11101431938197523},{-0.55384197390847578,-0.050566470413442005},{-0.55384197390847567,-0.050566470413441991},{-0.26983745787555147,-0.0052547216296739974},{-0.26983745787555141,-0.0052547216296739965},{-0.31654388864740896,0.43568878204907019},{-0.3165438886474089,0.43568878204907036},{-0.61249225825323961,-0.22656761299178974},{-0.6124922582532395,-0.22656761299178974},{0.51367288660745269,-0.14672923625352396},{0.51367288660745303,-0.14672923625352388},{-0.061000141880227648,-0.074830551323598726},{-0.061000141880227648,-0.074830551323598685},{0.063238932103082401,-0.37270373154309089},{0.063238932103082443,-0.37270373154309089},{-0.62397658294803937,-0.43378186506793615},{-0.62397658294803937,-0.43378186506793603},{-0.29620236141060108,-0.24082492622254642},{-0.29620236141060102,-0.24082492622254636},{-0.083639740457432318,0.46356733378080539},{-0.083639740457432291,0.46356733378080539},{-0.078697305567739684,0.75941463182384616},{-0.07869730556773967,0.75941463182384628},{0.55916155272340295,0.26005051714491845},{0.55916155272340329,0.26005051714491861},{0.0090991934471737479,-0.89256289692984836},{0.0090991934471737496,-0.89256289692984803},{-0.01551647656911137,-0.38885814801603924},{-0.015516476569111365,-0.38885814801603924},{-0.015670356144559389,-0.35794858260400381},{-0.015670356144559385,-0.35794858260400375},{0.44678146299056498,-0.052239411468506664},{0.44678146299056498,-0.05223941146850665},{1.0710389841912518,-0.27311320342893641},{1.0710389841912522,-0.27311320342893641},{0.23533790163003582,-0.23476194158747798},{0.23533790163003585,-0.23476194158747793},{0.079154249369266516,0.60365396283774164},{0.079154249369266516,0.60365396283774186},{0.63110443689995821,-0.65625646344149469},{0.63110443689995854,-0.65625646344149469},{-0.21077148265812098,0.032523815759867236},{-0.2107714826581209,0.03252381575986725},{-0.7231240597670221,-0.0065446272515531922},{-0.7231240597670221,-0.0065446272515531922},{-0.080605847597846642,0.13336777305165762},{-0.080605847597846628,0.13336777305165762},{0.48597827619774187,-0.6069162101181359},{0.48597827619774203,-0.6069162101181359},{-0.45074830552926259,0.19434862886898324},{-0.45074830552926248,0.19434862886898324},{0.28271958673836473,-0.22519487430374507},{0.28271958673836473,-0.22519487430374502},{-0.82150933463046472,-0.032680144359764129},{-0.82150933463046472,-0.032680144359764129},{-0.11933763497114419,0.25235131805383626},{-0.11933763497114419,0.25235131805383626},{-0.050641541900826315,-0.054813367860809092},{-0.050641541900826308,-0.054813367860809079},{0.37639163137503584,-0.049130237209268013},{0.37639163137503595,-0.049130237209268006},{0.27548991638682568,-1.2892018379461803},{0.27548991638682585,-1.28920183794618},{0.19113786193208002,-0.49992907513642937},{0.1911378619320801,-0.49992907513642931},{-0.18408107881733532,-0.67382832840964246},{-0.18408107881733524,-0.67382832840964246},{0.26736586776080096,0.35645201936711196},{0.26736586776080112,0.35645201936711196},{1.1765511302564113,-0.54808935964139494},{1.176551130256412,-0.54808935964139494},{1.1542398998705217,-0.31479529183636029},{1.1542398998705217,-0.31479529183636029},{-0.66898530245621757,0.80403775434581881},{-0.66898530245621723,0.80403775434581903},{0.24120212235388105,-0.074234715537873724},{0.24120212235388111,-0.074234715537873697},{0.5689391732853385,-0.4334628652354342},{0.56893917328533883,-0.43346286523543415},{-0.42290718604120192,0.11827577249881677},{-0.42290718604120192,0.11827577249881677},{-0.57213326941933329,0.26812444739865027},{-0.57213326941933329,0.26812444739865043},{-0.14648803653271852,0.43053167915776408},{-0.1464880365327185,0.43053167915776425},{0.053746239841527543,-0.44599592491477291},{0.053746239841527564,-0.44599592491477291},{0.58965301444953266,0.077356496594420787},{0.589653014449533,0.077356496594420815},{-0.25257596915203095,-0.18313436335008951},{-0.2525759691520309,-0.18313436335008942},{0.6519199000082152,0.81135021226898063},{0.65191990000821531,0.81135021226898096},{-0.20987680281715365,0.31018961232143716},{-0.2098768028171536,0.31018961232143721},{0.48885261554599502,-0.76948572639204571},{0.48885261554599502,-0.76948572639204571},{0.32498664525642773,0.35466894818618966},{0.3249866452564279,0.35466894818618983},{-0.21867254773101694,0.33653237135631914},{-0.21867254773101685,0.33653237135631919},{-0.1628632057456908,0.12513912098254698},{-0.16286320574569077,0.12513912098254704},{-0.2482127546806861,0.054592620932045616},{-0.24821275468068604,0.054592620932045637},{0.19972864932719311,0.48470032915534},{0.19972864932719311,0.48470032915534011},{0.51942037089080462,0.60868988910391053},{0.51942037089080495,0.60868988910391086},{0.19766219439600413,-0.62449434833587503},{0.19766219439600419,-0.6244943483358748},{-0.66597660589332963,0.56425079496422992},{-0.66597660589332941,0.56425079496423003},{0.63803037021963116,0.79114583271401728},{0.63803037021963116,0.79114583271401728},{-0.26395809443414059,1.0973674142268384},{-0.26395809443414053,1.0973674142268388},{-0.013043068475538544,-0.18048505417693753},{-0.013043068475538539,-0.1804850541769375},{-0.61774597831871225,-0.27799056685402013},{-0.61774597831871225,-0.27799056685401996},{0.65410203445801629,0.58212479252995397},{0.65410203445801662,0.5821247925299543},{-1.0384774049322054,0.80091936182779222},{-1.0384774049322048,0.80091936182779222},{-0.15543061695759031,0.44885645072316704},{-0.15543061695759022,0.4488564507231671},{-0.21901225075291414,0.029572470395186623},{-0.21901225075291408,0.029572470395186626},{0.066653495816932917,0.22784631400291541},{0.066653495816932959,0.22784631400291547},{-0.18730209014152358,-0.44204961843797247},{-0.18730209014152349,-0.44204961843797247},{-0.89541942227070681,-0.096227620515696444},{-0.89541942227070681,-0.096227620515696444},{0.68768134671484749,-0.10067450355909061},{0.6876813467148476,-0.10067450355909059},{0.80201448825561994,-0.45574445325538349},{0.80201448825562005,-0.45574445325538337},{0.11678579588295551,0.47780135965768722},{0.11678579588295553,0.47780135965768722},{-0.6173779479953273,-0.1463086195272349},{-0.61737794799532708,-0.14630861952723481},{0.041095702758869729,-0.38022576288843984},{0.041095702758869729,-0.38022576288843979},{0.83140034987569722,-0.48166469434786263},{0.83140034987569755,-0.48166469434786252},{-0.34174495946656352,0.23518527569853431},{-0.34174495946656336,0.23518527569853434},{-0.74723186423073595,-0.05533196936496787},{-0.74723186423073573,-0.055331969364967856},{0.44786515872763016,-0.85816620776194363},{0.44786515872763027,-0.85816620776194352},{0.23941964930595461,0.5685962507505915},{0.23941964930595466,0.5685962507505915},{-0.47370747024486054,-0.51821730620791895},{-0.47370747024486048,-0.51821730620791862},{-0.24686466238928517,0.51409809993715427},{-0.24686466238928517,0.51409809993715438},{0.44658693352833112,-0.37822156772624715},{0.44658693352833112,-0.37822156772624699},{0.72168402804110143,-0.12155234552799939},{0.72168402804110166,-0.12155234552799934},{0.015204864396908546,0.63766836183423536},{0.015204864396908548,0.6376683618342357},{-0.42393694982300156,-0.52180894773158815},{-0.42393694982300145,-0.52180894773158781},{0.074150788216010455,0.6371956908817733},{0.074150788216010469,0.63719569088177341},{-0.1903574628038755,-0.38684400671343444},{-0.19035746280387544,-0.38684400671343444},{-0.37735591312374572,0.0068579608273421355},{-0.37735591312374572,0.0068579608273421373},{0.085014668390940851,0.27421860297639405},{0.085014668390940892,0.27421860297639411},{1.3703190609240201,-0.67052423499952418},{1.3703190609240201,-0.67052423499952385},{0.22067502222484947,-0.42972719575427676},{0.22067502222484955,-0.42972719575427659},{0.44963247313734578,-0.59979049249040961},{0.44963247313734583,-0.59979049249040939},{0.46067690162157482,-0.40286637662936148},{0.46067690162157482,-0.40286637662936142},{0.20461881450521396,0.23845839738985905},{0.20461881450521396,0.23845839738985911},{-0.17702190369781501,0.0017472361069717779},{-0.17702190369781493,0.0017472361069717785},{0.33088666738271627,0.39635242461181414},{0.33088666738271644,0.39635242461181425},{-0.51267930309628962,-0.98168188911601284},{-0.5126793030962894,-0.98168188911601273},{-0.20315580021343643,0.25993483522132416},{-0.2031558002134364,0.25993483522132421},{0.01157315314252727,-0.075228658018301198},{0.011573153142527272,-0.07522865801830117},{-0.21228749537026559,1.0455265018271471},{-0.21228749537026559,1.0455265018271478},{-0.41189595397813739,0.25654637457806562},{-0.41189595397813733,0.25654637457806567},{-0.40504807761153394,-0.82676727968795904},{-0.40504807761153383,-0.82676727968795871},{0.87283700565815225,-0.84891462113306293},{0.87283700565815225,-0.8489146211330626},{-0.15484731030271964,0.29785436743332161},{-0.15484731030271962,0.29785436743332172},{0.95983959791516216,-0.021475535817715843},{0.95983959791516216,-0.021475535817715833},{-0.38137697569129481,0.7192828208488169},{-0.38137697569129464,0.71928282084881701},{0.21951101473819934,0.64808435007447884},{0.21951101473819934,0.64808435007447907},{-0.31134277440807212,0.045948715073330315},{-0.31134277440807195,0.045948715073330336},{-0.16009981684527497,-0.17250123317199526},{-0.16009981684527497,-0.17250123317199526},{0.25568807750253153,0.30423782531372767},{0.2556880775025317,0.30423782531372784},{0.25349785887205351,0.41258202395216825},{0.25349785887205356,0.41258202395216842},{-0.22823188438717018,0.35559091586133129},{-0.22823188438717018,0.3555909158613314},{-0.043847734475191566,0.54698888327213602},{-0.043847734475191552,0.54698888327213624},{0.0022848127328267687,0.16581911916150355},{0.0022848127328267695,0.16581911916150358},{-0.96645101673658207,0.57725560192229264},{-0.96645101673658185,0.57725560192229286},{0.19331577714046103,0.16819098929912168},{0.19331577714046111,0.16819098929912168},{0.88093802851270597,1.3996876457175011},{0.88093802851270631,1.3996876457175018},{-0.64032072255254535,0.22975969206145769},{-0.64032072255254502,0.22975969206145774},{-0.92699314492712404,-0.74046088874198313},{-0.9269931449271237,-0.74046088874198279},{-0.30368277421537726,-0.50554466993163683},{-0.3036827742153772,-0.5055446699316366},{0.54666946041448528,0.070047610389090131},{0.54666946041448539,0.070047610389090159},{0.25500851421300097,-0.29367076034138706},{0.25500851421300114,-0.29367076034138695},{0.15138727668563495,-0.0049418965549759275},{0.15138727668563501,-0.0049418965549759266},{-0.43887856303510187,0.81364773420308634},{-0.43887856303510181,0.81364773420308656},{-0.33880265875092413,-0.31551224415527107},{-0.33880265875092397,-0.31551224415527102},{1.377423681456482,0.012704561359672462},{1.377423681456482,0.012704561359672462},{-0.041263422421853435,0.40358448512677481},{-0.041263422421853414,0.40358448512677497},{-0.086101656449091735,-0.79867370107282332},{-0.086101656449091721,-0.79867370107282321},{0.38369189385308378,0.83900851560510326},{0.38369189385308383,0.83900851560510326},{-0.17307936456124118,-0.064747090477561553},{-0.17307936456124109,-0.064747090477561525},{-0.027534758237677759,-0.15870621273858665},{-0.027534758237677748,-0.15870621273858657},{-0.51169965223312952,-0.45534571166382642},{-0.51169965223312941,-0.45534571166382637},{0.60862698046731722,0.015815755110900165},{0.60862698046731756,0.015815755110900165},{-0.3066696359213093,-0.64907967189671945},{-0.3066696359213093,-0.64907967189671945},{0.25735828080127232,0.49429943061451787},{0.25735828080127243,0.49429943061451792},{-0.55735690252271042,0.10864971359925568},{-0.55735690252271008,0.1086497135992557},{0.10100854569812368,-0.57754007003057151},{0.10100854569812368,-0.57754007003057117},{0.16011849083924728,-0.51825017619247493},{0.16011849083924731,-0.51825017619247493},{1.1626364195660153,-0.027141868869618918},{1.1626364195660159,-0.027141868869618915},{-0.45286020053725284,0.46618578082394724},{-0.45286020053725279,0.46618578082394729},{0.32258327609642495,-0.21020161600148371},{0.32258327609642512,-0.21020161600148368},{-0.44690412490928921,-0.30385833257152894},{-0.4469041249092891,-0.30385833257152894},{0.83772240629732875,-0.52258760685285821},{0.83772240629732886,-0.5225876068528581},{-0.35063350958529577,-0.44521824304962737},{-0.35063350958529571,-0.44521824304962726},{0.042917945172412694,-0.26990725363183959},{0.042917945172412701,-0.26990725363183948},{0.28617439894992625,-0.6241441143108587},{0.28617439894992625,-0.62414411431085837},{-0.21331655993940007,1.1315954154549954},{-0.21331655993940002,1.1315954154549959},{-0.70716039865914126,-0.058736503090992098},{-0.70716039865914093,-0.058736503090992098},{-0.43104678259786616,-0.40319051035395231},{-0.43104678259786611,-0.40319051035395215},{0.47964732934672699,-0.62085579993624052},{0.47964732934672716,-0.6208557999362404},{-0.27104983788326825,0.0053388032312992328},{-0.2710498378832682,0.0053388032312992354},{-0.0041329173810210895,0.3935166528530436},{-0.0041329173810210887,0.39351665285304366}}; validate(coords2); } From b958e48b00696f3200632804befb972677f430a0 Mon Sep 17 00:00:00 2001 From: Blake Thompson Date: Tue, 30 Oct 2018 16:10:50 -0400 Subject: [PATCH 2/3] Small changes to organization of code --- include/delaunator.hpp | 146 ++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 75 deletions(-) diff --git a/include/delaunator.hpp b/include/delaunator.hpp index 93a8f69..e6f3695 100644 --- a/include/delaunator.hpp +++ b/include/delaunator.hpp @@ -109,51 +109,6 @@ inline bool check_pts_equal(HullPoint * pt1, HullPoint * pt2) { std::fabs(pt1->y - pt2->y) <= EPSILON; } -struct DelaunatorMap { - - std::vector values; - Point center; - - DelaunatorMap(std::size_t size, - Point const& center_): - values(size, nullptr), - center(center_) {} - - static double pseudo_angle(const double dx, const double dy) { - const double p = dx / (std::abs(dx) + std::abs(dy)); - return (dy > 0.0 ? 3.0 - p : 1.0 + p) / 4.0; // [0..1) - } - - std::size_t hash(const double x, const double y) const { - const double dx = x - center.x; - const double dy = y - center.y; - return fast_mod( - static_cast(std::llround(std::floor(pseudo_angle(dx, dy) * static_cast(values.size())))), - values.size()); - } - - void add(HullPoint * pt) { - values[hash(pt->x, pt->y)] = pt; - } - - HullPoint * find(const double x, const double y) { - auto start = values.begin() + static_cast::difference_type>(hash(x, y)); - - for (auto iter = start; iter != values.end(); ++iter) { - if (*iter != nullptr && (*iter)->next != nullptr) { - return *iter; - } - } - for (auto iter = values.begin(); iter != start; ++iter) { - if (*iter != nullptr && (*iter)->next != nullptr) { - return *iter; - } - } - // Should not reach here under normal operation - return nullptr; - } -}; - struct DelaunatorHull { std::vector points; @@ -280,50 +235,84 @@ struct DelaunatorHull { } return closest; } +}; +struct DelaunatorMap { + + std::vector values; + Point center; + + DelaunatorMap(std::size_t size, + Point const& center_): + values(size, nullptr), + center(center_) {} + + static double pseudo_angle(const double dx, const double dy) { + const double p = dx / (std::abs(dx) + std::abs(dy)); + return (dy > 0.0 ? 3.0 - p : 1.0 + p) / 4.0; // [0..1) + } + + std::size_t hash(const double x, const double y) const { + const double dx = x - center.x; + const double dy = y - center.y; + return fast_mod( + static_cast(std::floor(pseudo_angle(dx, dy) * static_cast(values.size()))), + values.size()); + } + + void add(HullPoint * pt) { + values[hash(pt->x, pt->y)] = pt; + } + + HullPoint * find(HullPoint * pt) { + auto start = values.begin() + static_cast::difference_type>(hash(pt->x, pt->y)); + + for (auto iter = start; iter != values.end(); ++iter) { + if (*iter != nullptr && (*iter)->next != nullptr) { + return *iter; + } + } + for (auto iter = values.begin(); iter != start; ++iter) { + if (*iter != nullptr && (*iter)->next != nullptr) { + return *iter; + } + } + // Should not reach here under normal operation + return nullptr; + } }; struct DelaunatorResult { std::vector triangles; std::vector halfedges; + std::size_t current_triangle_index; std::size_t hull_start; bool success; DelaunatorResult(): triangles(), halfedges(), + current_triangle_index(0), hull_start(0), success(false) {} DelaunatorResult(std::size_t size): - triangles(), - halfedges(), + triangles(size, INVALID_INDEX), + halfedges(size, INVALID_INDEX), + current_triangle_index(0), hull_start(0), - success(false) { - std::size_t max_triangles = size < 3 ? 1 : 2 * size - 5; - triangles.reserve(max_triangles * 3); - halfedges.reserve(max_triangles * 3); + success(false) {} + + void trim() { + triangles.erase(triangles.begin() + static_cast::difference_type>(current_triangle_index), triangles.end()); + halfedges.erase(halfedges.begin() + static_cast::difference_type>(current_triangle_index), halfedges.end()); } void link(std::size_t a, std::size_t b) { - std::size_t s = halfedges.size(); - if (a == s) { - halfedges.push_back(b); - } else if (a < s) { - halfedges[a] = b; - } else { - throw std::runtime_error("Cannot link edge"); - } + halfedges[a] = b; if (b != INVALID_INDEX) { - std::size_t s2 = halfedges.size(); - if (b == s2) { - halfedges.push_back(a); - } else if (b < s2) { - halfedges[b] = a; - } else { - throw std::runtime_error("Cannot link edge"); - } + halfedges[b] = a; } } @@ -333,13 +322,14 @@ struct DelaunatorResult { std::size_t a, std::size_t b, std::size_t c) { - std::size_t t = triangles.size(); - triangles.push_back(i0); - triangles.push_back(i1); - triangles.push_back(i2); + std::size_t t = current_triangle_index; + triangles[t] = i0; + triangles[t+1] = i1; + triangles[t+2] = i2; link(t, a); link(t + 1, b); link(t + 2, c); + current_triangle_index += 3; return t; } @@ -377,6 +367,10 @@ struct DelaunatorResult { return ar; } + // The biggest performance issue is the cache miss that occurs + // when we go back to the HullPoint vector in points to get the + // x, y position of the points for "in_circle". As legalize is a very + // tight loop, this call accounts for a large amount of our processing. bool illegal = in_circle(hull.points[p0], hull.points[pr], hull.points[pl], @@ -422,8 +416,9 @@ DelaunatorResult delaunator(std::vector const& coords) { // Not enough points to triangulate return DelaunatorResult(); } - - DelaunatorResult result(point_size); + + std::size_t max_triangles = point_size < 3 ? 1 : 2 * point_size - 5; + DelaunatorResult result(max_triangles * 3); DelaunatorHull hull(coords); @@ -440,7 +435,7 @@ DelaunatorResult delaunator(std::vector const& coords) { hull.sort(center); - std::size_t hash_size = static_cast(std::llround(std::ceil(std::sqrt(point_size)))); + std::size_t hash_size = static_cast(std::ceil(std::sqrt(point_size))); DelaunatorMap hash(hash_size, center); // Setup linking of first points now @@ -473,7 +468,7 @@ DelaunatorResult delaunator(std::vector const& coords) { check_pts_equal(pt, pt2)) continue; // find a visible edge on the convex hull using edge hash - auto start = hash.find(pt->x, pt->y); + auto start = hash.find(pt); if (!start) { throw std::runtime_error("No values in hash"); @@ -542,6 +537,7 @@ DelaunatorResult delaunator(std::vector const& coords) { hash.add(e); } result.success = true; + result.trim(); return result; } /* From d990d1739ffeda6c590539609b20bee8a7dcecff Mon Sep 17 00:00:00 2001 From: Blake Thompson Date: Tue, 30 Oct 2018 16:33:08 -0400 Subject: [PATCH 3/3] Forgot to add sorted_points to constructor initialization list --- include/delaunator.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/delaunator.hpp b/include/delaunator.hpp index e6f3695..19d0b30 100644 --- a/include/delaunator.hpp +++ b/include/delaunator.hpp @@ -118,6 +118,7 @@ struct DelaunatorHull { template DelaunatorHull(PointContainer const& coords): points(), + sorted_points(), start_index(0) { points.reserve(coords.size()); sorted_points.reserve(coords.size());