OrcaSlicer/tests/libslic3r/test_voronoi.cpp
coryrc 52c2a85d28
Fix tests (#10906)
* Get libslic3r tests closer to passing

I can't get geometry tests to do anything useful. I've added extra
output, but it hasn't helped me figure out why they don't work
yet. That's also probably the last broken 3mf test doesn't work.

The config tests were mostly broken because of config name changes.

The placeholder_parser tests have some things that may-or-may-not
still apply to Orca.

* Vendor a 3.x version of Catch2

Everything is surely broken at this point.

* Allow building tests separately from Orca with build_linux.sh

* Remove unnecessary log message screwing up ctest

Same solution as Prusaslicer

* Make 2 TriangleMesh methods const

Since they can be.

* Move method comment to the header where it belongsc

* Add indirectly-included header directly

Transform3d IIRC

* libslic3r tests converted to Catch2 v3

Still has 3 failing tests, but builds and runs.

* Disable 2D convex hull test and comment what I've learned

Not sure the best way to solve this yet.

* Add diff compare method for DynamicConfig

Help the unit test report errors better.

* Perl no longer used, remove comment line

* Clang-format Config.?pp

So difficult to work with ATM

* Remove cpp17 unit tests

Who gives a shit

* Don't need explicit "example" test

We have lots of tests to serve as examples.

* Leave breadcrumb to enable sla_print tests

* Fix serialization of DynamicConfig

Add comments to test, because these code paths might not be even used
anymore.

* Update run_unit_tests to run all the tests

By the time I'm done with the PR all tests will either excluded by
default or passing, so just do all.

* Update how-to-test now that build_linux.sh builds tests separately

* Update cmake regenerate instructions

Read this online; hopefully works.

* Enable slic3rutils test with Catch2 v3

* Port libnest2d and fff_print to Catch2 v3

They build. Many failing.

* Add slightly more info to Objects not fit on bed exception

* Disable failing fff_print tests from running

They're mostly failing for "objects don't fit on bed" for an
infinite-sized bed. Given infinite bed is probably only used in tests,
it probably was incidentally broken long ago.

* Must checkout tests directory in GH Actions

So we get the test data

* Missed a failing fff_print test

* Disable (most/all) broken libnest2d tests

Trying all, not checking yet though

* Fix Polygon convex/concave detection tests

Document the implementation too. Reorganize the tests to be cleaner.

* Update the test script to run tests in parallel

* Get sla_print tests to build

Probably not passing

* Don't cause full project rebuild when updating test CMakeLists.txts

* Revert "Clang-format Config.?pp"

This reverts commit 771e4c0ad2.

---------

Co-authored-by: SoftFever <softfeverever@gmail.com>
2025-12-08 22:42:11 +08:00

2163 lines
92 KiB
C++

#include <catch2/catch_all.hpp>
#include "test_utils.hpp"
#include <libslic3r/Polygon.hpp>
#include <libslic3r/Polyline.hpp>
#include <libslic3r/EdgeGrid.hpp>
#include <libslic3r/Geometry.hpp>
#include <libslic3r/Geometry/VoronoiOffset.hpp>
#include <libslic3r/Geometry/VoronoiVisualUtils.hpp>
#include <numeric>
#include <random>
// #define VORONOI_DEBUG_OUT
#ifdef VORONOI_DEBUG_OUT
#include <libslic3r/VoronoiVisualUtils.hpp>
#endif
using boost::polygon::voronoi_builder;
using boost::polygon::voronoi_diagram;
using boost::polygon::construct_voronoi;
using namespace Slic3r;
using VD = Geometry::VoronoiDiagram;
using BoostVD = boost::polygon::voronoi_diagram<double>;
// https://svn.boost.org/trac10/ticket/12067
// This bug seems to be confirmed.
// Vojtech supposes that there may be no Voronoi edges produced for
// the 1st and last sweep line positions.
TEST_CASE("Voronoi missing edges - points 12067", "[Voronoi]")
{
Points pts {
{ -10, -20 },
{ 10, -20 },
{ 5, 0 },
{ 10, 20 },
{ -10, 20 },
{ -5, 0 }
};
#if 0
for (Point &p : pts) {
Vec2d q = p.cast<double>();
p.x() = scale_(p.x());
p.y() = scale_(p.y());
}
#endif
#if 0
// Try to rotate, maybe the issue is caused by incorrect handling of vertical or horizontal edges?
double a = 0.18764587962597876897475f;
double c = cos(a);
double s = sin(a);
for (Point &p : poly.points) {
Vec2d q = p.cast<double>();
p.x() = coord_t(q.x() * c + q.y() * s + 0.5);
p.y() = coord_t(- q.x() * s + q.y() * c + 0.5);
}
#endif
// Construction of the Voronoi Diagram.
BoostVD vd;
construct_voronoi(pts.begin(), pts.end(), &vd);
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-pts.svg").c_str(),
vd, pts, Lines());
#endif
// REQUIRE(closest_point.z() == Catch::Approx(1.));
}
// https://svn.boost.org/trac10/ticket/12707
// This issue is confirmed, there are no self intersections in the polygon.
// A minimal test case is created at the end of this test,
// a new issue opened with the minimal test case:
// https://github.com/boostorg/polygon/issues/43
TEST_CASE("Voronoi missing edges - Alessandro gapfill 12707", "[Voronoi]")
{
Lines lines0 {
{ { 42127548, 699996}, { 42127548, 10135750 } },
{ { 42127548, 10135750}, { 50487352, 10135750 } },
{ { 50487352, 10135750}, { 50487352, 699995 } },
{ { 50487352, 699995}, { 51187348, 0 } },
{ { 51187348, 0}, { 64325952, 0 } },
{ { 64325952, 0}, { 64325952, 699996 } },
{ { 64325952, 699996}, { 51187348, 699996 } },
{ { 51187348, 699996}, { 51187348, 10835701 } },
{ { 51187348, 10835701}, { 41427552, 10835701 } },
{ { 41427552, 10835701}, { 41427552, 699996 } },
{ { 41427552, 699996}, { 28664848, 699996 } },
{ { 28664848, 699996}, { 28664848, 10835701 } },
{ { 28664848, 10835701}, { 19280052, 10835701 } },
{ { 19280052, 10835701}, { 27964852, 699996 } },
{ { 27964852, 699996}, { 28664848, 0 } },
{ { 28664848, 0}, { 41427551, 0 } },
{ { 41427551, 0}, { 42127548, 699996 } }
};
Lines lines1 {
{ { 42127548, 699996}, { 42127548, 10135750 } },
{ { 42127548, 10135750}, { 50487352, 10135750 } },
{ { 50487352, 10135750}, { 50487352, 699995 } },
{ { 50487352, 699995}, { 51187348, 0 } },
{ { 51187348, 0}, { 51187348, 10835701 } },
{ { 51187348, 10835701}, { 41427552, 10835701 } },
{ { 41427552, 10835701}, { 41427552, 699996 } },
{ { 41427552, 699996}, { 28664848, 699996 } },
{ { 28664848, 699996}, { 28664848, 10835701 } },
{ { 28664848, 10835701}, { 19280052, 10835701 } },
{ { 19280052, 10835701}, { 27964852, 699996 } },
{ { 27964852, 699996}, { 28664848, 0 } },
{ { 28664848, 0}, { 41427551, 0 } },
{ { 41427551, 0}, { 42127548, 699996 } }
};
Lines lines2 {
{ { 42127548, 699996}, { 42127548, 10135750 } },
{ { 42127548, 10135750}, { 50487352, 10135750 } },
{ { 50487352, 10135750}, { 50487352, 699995 } },
{ { 50487352, 699995}, { 51187348, 0 } },
{ { 51187348, 0}, { 51187348, 10835701 } },
{ { 51187348, 10835701}, { 41427552, 10835701 } },
{ { 41427552, 10835701}, { 41427552, 699996 } },
{ { 41427552, 699996}, { 28664848, 699996 } },
{ { 28664848, 699996}, { 28664848, 10835701 } },
{ { 28664848, 10835701}, { 19280052, 10835701 } },
{ { 19280052, 10835701}, { 28664848, 0 } },
{ { 28664848, 0}, { 41427551, 0 } },
{ { 41427551, 0}, { 42127548, 699996 } }
};
Lines lines3 {
{ { 42127548, 699996}, { 42127548, 10135750 } },
{ { 42127548, 10135750}, { 50487352, 10135750 } },
{ { 50487352, 10135750}, { 50487352, 699995 } },
{ { 50487352, 699995}, { 51187348, 0 } },
{ { 51187348, 0}, { 51187348, 10835701 } },
{ { 51187348, 10835701}, { 41427552, 10835701 } },
{ { 41427552, 10835701}, { 41427552, 699996 } },
{ { 41427552, 699996}, { 41427551, 0 } },
{ { 41427551, 0}, { 42127548, 699996 } }
};
Lines lines4 {
{ { 42127548, 699996}, { 42127548, 10135750 } },
{ { 42127548, 10135750}, { 50487352, 10135750 } },
{ { 50487352, 10135750}, { 50487352, 699995 } },
{ { 50487352, 699995}, { 51187348, 0 } },
{ { 51187348, 0}, { 51187348, 10835701 } },
{ { 51187348, 10835701}, { 41427552, 10835701 } },
{ { 41427552, 10835701}, { 41427551, 0 } },
{ { 41427551, 0}, { 42127548, 699996 } }
};
Polygon poly {
{ 0, 10000000},
{ 700000, 1}, // it has to be 1, higher number, zero or -1 work.
{ 700000, 9000000},
{ 9100000, 9000000},
{ 9100000, 0},
{10000000, 10000000}
};
#if 1
// Try to rotate, maybe the issue is caused by incorrect handling of vertical or horizontal edges?
double a = 0.18764587962597876897475f;
double c = cos(a);
double s = sin(a);
for (Point &p : poly.points) {
Vec2d q = p.cast<double>();
p.x() = coord_t(q.x() * c + q.y() * s + 0.5);
p.y() = coord_t(- q.x() * s + q.y() * c + 0.5);
}
#endif
std::mt19937 gen;
std::uniform_int_distribution<coord_t> dist(-100, 100);
#if 0
for (Point &p : poly.points) {
// Wiggle the points a bit to find out whether this fixes the voronoi diagram for this particular polygon.
p.x() = (p.x() += dist(gen));
p.y() = (p.y() += dist(gen));
}
#endif
REQUIRE(intersecting_edges({ poly }).empty());
Lines lines = to_lines(poly);
BoostVD vd;
construct_voronoi(lines.begin(), lines.end(), &vd);
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-lines.svg").c_str(),
vd, Points(), lines);
#endif
}
TEST_CASE("Voronoi weirdness", "[Voronoi]")
{
Polygon poly2 {
{ 0, 0 },
{ 70000000, 0 },
{ 70000000, 1300000 },
// { 70000001, 14000000 }
{ 70700000, 14000000 }
};
Polygon poly5 {
{ 35058884, -25732145 },
{ 35058884, -19586070 },
{ 32753739, -20246796 },
{ 28756244, -21010725 },
{ 24657532, -21657939 },
{ 20836260, -21960233 },
{ 16115145, -22070742 },
{ 11850152, -21839761 },
{ 7646240, -21470177 },
{ 3607605, -20786940 },
{ 1280947, -20329742 },
{ -292823, -19963790 },
{ -3844469, -18809741 },
{ -7237277, -17593723 },
{ -10225900, -16143761 },
{ -13030266, -14643721 },
{ -15404294, -12977561 },
{ -17601713, -11280712 },
{ -19241930, -9435607 },
{ -20714420, -7583739 },
{ -21726144, -5664355 },
{ -22579294, -3741947 },
{ -22966684, -1786321 },
{ -23200322, 170140 },
{ -22966684, 2126602 },
{ -22579296, 4082227 },
{ -21726148, 6004637 },
{ -20714424, 7924020 },
{ -19241932, 9775888 },
{ -17601717, 11620994 },
{ -15404423, 13317749 },
{ -13030276, 14984003 },
{ -10225910, 16484042 },
{ -7237288, 17934005 },
{ -3844482, 19150025 },
{ -292841, 20304074 },
{ 1280949, 20670031 },
{ 3607587, 21127226 },
{ 7646218, 21810465 },
{ 11850128, 22180055 },
{ 16115122, 22411036 },
{ 20836263, 22300531 },
{ 24657513, 21998239 },
{ 28756227, 21351025 },
{ 32753725, 20587092 },
{ 35058893, 19926309 },
{ 35058893, 35000000 },
{ -31657232, 35000000 },
{ -31657202, -35000000 },
{ 35058881, -35000000 }
};
Polygon poly7 {
{ 35058884, -25732145 },
{ 35058884, -19586070 },
{ -31657202, -35000000 },
{ 35058881, -35000000 }
};
// coord_t shift = 35058881;
// coord_t shift_ok = 17000000;
coord_t shift = 35058881;
Polygon poly {
// <-4, 0>: bug
// -5: ok
// 1 - ok
{ 0 + shift, -35000000 },
{ 0 + shift, -25732145 },
{ 0 + shift, -19586070 },
{ -66716086 + shift, -35000000 }
};
REQUIRE(intersecting_edges({ poly }).empty());
REQUIRE(poly.area() > 0.);
#if 0
// Try to rotate, maybe the issue is caused by incorrect handling of vertical or horizontal edges?
double a = 0.18764587962597876897475f;
double c = cos(a);
double s = sin(a);
for (Point &p : poly.points) {
Vec2d q = p.cast<double>();
p.x() = coord_t(q.x() * c + q.y() * s + 0.5);
p.y() = coord_t(- q.x() * s + q.y() * c + 0.5);
}
#endif
BoostVD vd;
Lines lines = to_lines(poly);
construct_voronoi(lines.begin(), lines.end(), &vd);
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-weirdness.svg").c_str(),
vd, Points(), lines);
#endif
}
// https://svn.boost.org/trac10/ticket/12903
// division by zero reported, but this issue is most likely a non-issue, as it produces an infinity for the interval of validity
// of the floating point calculation, therefore forcing a recalculation with extended accuracy.
TEST_CASE("Voronoi division by zero 12903", "[Voronoi]")
{
Points pts { { 1, 1 }, { 3, 1 }, { 1, 3 }, { 3, 3 },
{ -1, 1 }, { 1, -1 }, { 5, 1 }, { 3, -1 },
{ -1, 3 }, { 1, 5 }, { 5, 3 }, { 3, 5 } };
{
auto pts2 { pts };
std::sort(pts2.begin(), pts2.end(), [](auto &l, auto &r) { return (l.x() == r.x()) ? l.y() < r.y() : l.x() < r.x(); });
// No point removed -> no duplicate.
REQUIRE(std::unique(pts2.begin(), pts2.end()) == pts2.end());
}
BoostVD vd;
construct_voronoi(pts.begin(), pts.end(), &vd);
#ifdef VORONOI_DEBUG_OUT
// Scale the voronoi vertices and input points, so that the dump_voronoi_to_svg will display them correctly.
for (auto &pt : vd.vertices()) {
const_cast<double&>(pt.x()) = scale_(pt.x());
const_cast<double&>(pt.y()) = scale_(pt.y());
}
for (auto &pt : pts)
pt = Point::new_scale(pt.x(), pt.y());
dump_voronoi_to_svg(debug_out_path("voronoi-div-by-zero.svg").c_str(), vd, pts, Lines());
#endif
}
// https://svn.boost.org/trac10/ticket/12139
// Funny sample from a dental industry?
// Vojtech confirms this test fails and rightly so, because the input data contain self intersections.
// This test is suppressed.
TEST_CASE("Voronoi NaN coordinates 12139", "[Voronoi][.][!mayfail]")
{
Lines lines = {
{ { 260500,1564400 }, { 261040,1562960 } },
{ { 261040,1562960 }, { 260840,1561780 } },
{ { 260840,1561780 }, { 262620,1561480 } },
{ { 262620,1561480 }, { 263160,1561220 } },
{ { 263160,1561220 }, { 264100,1563259 } },
{ { 264100,1563259 }, { 262380,1566980 } },
{ { 262380,1566980 }, { 260500,1564400 } },
{ { 137520,1851640 }, { 132160,1851100 } },
{ { 132160,1851100 }, { 126460,1848779 } },
{ { 126460,1848779 }, { 123960,1847320 } },
{ { 123960,1847320 }, { 120960,1844559 } },
{ { 120960,1844559 }, { 119640,1843040 } },
{ { 119640,1843040 }, { 118320,1840900 } },
{ { 118320,1840900 }, { 117920,1838120 } },
{ { 117920,1838120 }, { 118219,1833340 } },
{ { 118219,1833340 }, { 116180,1835000 } },
{ { 116180,1835000 }, { 115999,1834820 } },
{ { 115999,1834820 }, { 114240,1836340 } },
{ { 114240,1836340 }, { 112719,1837260 } },
{ { 112719,1837260 }, { 109460,1838239 } },
{ { 109460,1838239 }, { 103639,1837480 } },
{ { 103639,1837480 }, { 99819,1835460 } },
{ { 99819,1835460 }, { 96320,1834260 } },
{ { 96320,1834260 }, { 95339,1834260 } },
{ { 95339,1834260 }, { 93660,1833720 } },
{ { 93660,1833720 }, { 90719,1833300 } },
{ { 90719,1833300 }, { 87860,1831660 } },
{ { 87860,1831660 }, { 84580,1830499 } },
{ { 84580,1830499 }, { 79780,1827419 } },
{ { 79780,1827419 }, { 76020,1824280 } },
{ { 76020,1824280 }, { 73680,1821180 } },
{ { 73680,1821180 }, { 72560,1818960 } },
{ { 72560,1818960 }, { 71699,1817719 } },
{ { 71699,1817719 }, { 70280,1814260 } },
{ { 70280,1814260 }, { 69460,1811060 } },
{ { 69460,1811060 }, { 69659,1807320 } },
{ { 69659,1807320 }, { 69640,1803300 } },
{ { 69640,1803300 }, { 69360,1799780 } },
{ { 69360,1799780 }, { 69320,1796720 } },
{ { 69320,1796720 }, { 69640,1793980 } },
{ { 69640,1793980 }, { 70160,1791780 } },
{ { 70160,1791780 }, { 72460,1784879 } },
{ { 72460,1784879 }, { 74420,1780780 } },
{ { 74420,1780780 }, { 76500,1772899 } },
{ { 76500,1772899 }, { 76760,1769359 } },
{ { 76760,1769359 }, { 76480,1766259 } },
{ { 76480,1766259 }, { 76839,1760360 } },
{ { 76839,1760360 }, { 77539,1756680 } },
{ { 77539,1756680 }, { 80540,1748140 } },
{ { 80540,1748140 }, { 84200,1742619 } },
{ { 84200,1742619 }, { 90900,1735220 } },
{ { 90900,1735220 }, { 94159,1732679 } },
{ { 94159,1732679 }, { 101259,1729559 } },
{ { 101259,1729559 }, { 107299,1727939 } },
{ { 107299,1727939 }, { 110979,1727919 } },
{ { 110979,1727919 }, { 113499,1727240 } },
{ { 113499,1727240 }, { 113619,1727359 } },
{ { 113619,1727359 }, { 114280,1727280 } },
{ { 114280,1727280 }, { 131440,1732560 } },
{ { 131440,1732560 }, { 118140,1727119 } },
{ { 118140,1727119 }, { 117120,1723759 } },
{ { 117120,1723759 }, { 113840,1720660 } },
{ { 113840,1720660 }, { 111399,1716760 } },
{ { 111399,1716760 }, { 109700,1712979 } },
{ { 109700,1712979 }, { 108879,1708400 } },
{ { 108879,1708400 }, { 108060,1696360 } },
{ { 108060,1696360 }, { 110040,1687760 } },
{ { 110040,1687760 }, { 112140,1682480 } },
{ { 112140,1682480 }, { 112540,1681780 } },
{ { 112540,1681780 }, { 115260,1678320 } },
{ { 115260,1678320 }, { 118720,1675320 } },
{ { 118720,1675320 }, { 126100,1670980 } },
{ { 126100,1670980 }, { 132400,1668080 } },
{ { 132400,1668080 }, { 136700,1667440 } },
{ { 136700,1667440 }, { 142440,1667159 } },
{ { 142440,1667159 }, { 143340,1666720 } },
{ { 143340,1666720 }, { 138679,1661319 } },
{ { 138679,1661319 }, { 137240,1657480 } },
{ { 137240,1657480 }, { 136760,1650739 } },
{ { 136760,1650739 }, { 136780,1647339 } },
{ { 136780,1647339 }, { 135940,1644280 } },
{ { 135940,1644280 }, { 136000,1640820 } },
{ { 136000,1640820 }, { 135480,1638020 } },
{ { 135480,1638020 }, { 137060,1634220 } },
{ { 137060,1634220 }, { 136320,1631340 } },
{ { 136320,1631340 }, { 134620,1629700 } },
{ { 134620,1629700 }, { 132460,1628199 } },
{ { 132460,1628199 }, { 132299,1627860 } },
{ { 132299,1627860 }, { 138360,1618020 } },
{ { 138360,1618020 }, { 142440,1611859 } },
{ { 142440,1611859 }, { 143180,1611299 } },
{ { 143180,1611299 }, { 144000,1611259 } },
{ { 144000,1611259 }, { 145960,1612540 } },
{ { 145960,1612540 }, { 146720,1613700 } },
{ { 146720,1613700 }, { 147700,1613539 } },
{ { 147700,1613539 }, { 148520,1614039 } },
{ { 148520,1614039 }, { 149840,1613740 } },
{ { 149840,1613740 }, { 150620,1614079 } },
{ { 150620,1614079 }, { 154760,1612740 } },
{ { 154760,1612740 }, { 159000,1608420 } },
{ { 159000,1608420 }, { 161120,1606780 } },
{ { 161120,1606780 }, { 164060,1605139 } },
{ { 164060,1605139 }, { 168079,1603620 } },
{ { 168079,1603620 }, { 170240,1603400 } },
{ { 170240,1603400 }, { 172400,1603499 } },
{ { 172400,1603499 }, { 194440,1613740 } },
{ { 194440,1613740 }, { 195880,1616460 } },
{ { 195880,1616460 }, { 197060,1618140 } },
{ { 197060,1618140 }, { 198039,1617860 } },
{ { 198039,1617860 }, { 198739,1618900 } },
{ { 198739,1618900 }, { 200259,1619200 } },
{ { 200259,1619200 }, { 201940,1618920 } },
{ { 201940,1618920 }, { 201700,1617139 } },
{ { 201700,1617139 }, { 203860,1618179 } },
{ { 203860,1618179 }, { 203500,1617540 } },
{ { 203500,1617540 }, { 205000,1616579 } },
{ { 205000,1616579 }, { 206780,1615020 } },
{ { 206780,1615020 }, { 210159,1614059 } },
{ { 210159,1614059 }, { 217080,1611080 } },
{ { 217080,1611080 }, { 219200,1611579 } },
{ { 219200,1611579 }, { 223219,1610980 } },
{ { 223219,1610980 }, { 224580,1610540 } },
{ { 224580,1610540 }, { 227460,1611440 } },
{ { 227460,1611440 }, { 229359,1611859 } },
{ { 229359,1611859 }, { 230620,1612580 } },
{ { 230620,1612580 }, { 232340,1614460 } },
{ { 232340,1614460 }, { 232419,1617040 } },
{ { 232419,1617040 }, { 231740,1619480 } },
{ { 231740,1619480 }, { 231880,1624899 } },
{ { 231880,1624899 }, { 231540,1625820 } },
{ { 231540,1625820 }, { 231700,1627079 } },
{ { 231700,1627079 }, { 231320,1628239 } },
{ { 231320,1628239 }, { 231420,1636080 } },
{ { 231420,1636080 }, { 231099,1637200 } },
{ { 231099,1637200 }, { 228660,1643280 } },
{ { 228660,1643280 }, { 227699,1644960 } },
{ { 227699,1644960 }, { 226080,1651140 } },
{ { 226080,1651140 }, { 225259,1653420 } },
{ { 225259,1653420 }, { 225159,1655399 } },
{ { 225159,1655399 }, { 223760,1659260 } },
{ { 223760,1659260 }, { 219860,1666360 } },
{ { 219860,1666360 }, { 219180,1667220 } },
{ { 219180,1667220 }, { 212580,1673680 } },
{ { 212580,1673680 }, { 207880,1676460 } },
{ { 207880,1676460 }, { 205560,1677560 } },
{ { 205560,1677560 }, { 199700,1678920 } },
{ { 199700,1678920 }, { 195280,1679420 } },
{ { 195280,1679420 }, { 193939,1679879 } },
{ { 193939,1679879 }, { 188780,1679440 } },
{ { 188780,1679440 }, { 188100,1679639 } },
{ { 188100,1679639 }, { 186680,1679339 } },
{ { 186680,1679339 }, { 184760,1679619 } },
{ { 184760,1679619 }, { 183520,1681440 } },
{ { 183520,1681440 }, { 183860,1682200 } },
{ { 183860,1682200 }, { 186620,1686120 } },
{ { 186620,1686120 }, { 190380,1688380 } },
{ { 190380,1688380 }, { 192780,1690739 } },
{ { 192780,1690739 }, { 195860,1694839 } },
{ { 195860,1694839 }, { 196620,1696539 } },
{ { 196620,1696539 }, { 197540,1701819 } },
{ { 197540,1701819 }, { 198939,1705699 } },
{ { 198939,1705699 }, { 198979,1711819 } },
{ { 198979,1711819 }, { 198240,1716900 } },
{ { 198240,1716900 }, { 197440,1720139 } },
{ { 197440,1720139 }, { 195340,1724639 } },
{ { 195340,1724639 }, { 194040,1726140 } },
{ { 194040,1726140 }, { 192559,1728239 } },
{ { 192559,1728239 }, { 187780,1732339 } },
{ { 187780,1732339 }, { 182519,1735520 } },
{ { 182519,1735520 }, { 181239,1736140 } },
{ { 181239,1736140 }, { 177340,1737619 } },
{ { 177340,1737619 }, { 175439,1738140 } },
{ { 175439,1738140 }, { 171380,1738880 } },
{ { 171380,1738880 }, { 167860,1739059 } },
{ { 167860,1739059 }, { 166040,1738920 } },
{ { 166040,1738920 }, { 163680,1738539 } },
{ { 163680,1738539 }, { 157660,1736859 } },
{ { 157660,1736859 }, { 154900,1735460 } },
{ { 154900,1735460 }, { 151420,1735159 } },
{ { 151420,1735159 }, { 142100,1736160 } },
{ { 142100,1736160 }, { 140880,1735920 } },
{ { 140880,1735920 }, { 142820,1736859 } },
{ { 142820,1736859 }, { 144080,1737240 } },
{ { 144080,1737240 }, { 144280,1737460 } },
{ { 144280,1737460 }, { 144239,1738120 } },
{ { 144239,1738120 }, { 144980,1739420 } },
{ { 144980,1739420 }, { 146340,1741039 } },
{ { 146340,1741039 }, { 147160,1741720 } },
{ { 147160,1741720 }, { 154260,1745800 } },
{ { 154260,1745800 }, { 156560,1746879 } },
{ { 156560,1746879 }, { 165180,1752679 } },
{ { 165180,1752679 }, { 168240,1755860 } },
{ { 168240,1755860 }, { 170940,1759260 } },
{ { 170940,1759260 }, { 173440,1762079 } },
{ { 173440,1762079 }, { 174540,1764079 } },
{ { 174540,1764079 }, { 176479,1766640 } },
{ { 176479,1766640 }, { 178900,1768960 } },
{ { 178900,1768960 }, { 180819,1772780 } },
{ { 180819,1772780 }, { 181479,1776859 } },
{ { 181479,1776859 }, { 181660,1788499 } },
{ { 181660,1788499 }, { 181460,1791740 } },
{ { 181460,1791740 }, { 181160,1792840 } },
{ { 181160,1792840 }, { 179580,1797180 } },
{ { 179580,1797180 }, { 174620,1808960 } },
{ { 174620,1808960 }, { 174100,1809839 } },
{ { 174100,1809839 }, { 171660,1812419 } },
{ { 171660,1812419 }, { 169639,1813840 } },
{ { 169639,1813840 }, { 168880,1814720 } },
{ { 168880,1814720 }, { 168960,1815980 } },
{ { 168960,1815980 }, { 169979,1819160 } },
{ { 169979,1819160 }, { 170080,1820159 } },
{ { 170080,1820159 }, { 168280,1830540 } },
{ { 168280,1830540 }, { 167580,1832200 } },
{ { 167580,1832200 }, { 165679,1835720 } },
{ { 165679,1835720 }, { 164720,1836819 } },
{ { 164720,1836819 }, { 161840,1841740 } },
{ { 161840,1841740 }, { 159880,1843519 } },
{ { 159880,1843519 }, { 158959,1844120 } },
{ { 158959,1844120 }, { 154960,1847500 } },
{ { 154960,1847500 }, { 152140,1848580 } },
{ { 152140,1848580 }, { 150440,1849520 } },
{ { 150440,1849520 }, { 144940,1850980 } },
{ { 144940,1850980 }, { 138340,1851700 } },
{ { 138340,1851700 }, { 137520,1851640 } },
{ { 606940,1873860 }, { 602860,1872460 } },
{ { 602860,1872460 }, { 600680,1871539 } },
{ { 600680,1871539 }, { 599300,1870640 } },
{ { 599300,1870640 }, { 598120,1869579 } },
{ { 598120,1869579 }, { 594680,1867180 } },
{ { 594680,1867180 }, { 589680,1861460 } },
{ { 589680,1861460 }, { 586300,1855020 } },
{ { 586300,1855020 }, { 584700,1848060 } },
{ { 584700,1848060 }, { 585199,1843499 } },
{ { 585199,1843499 }, { 584000,1842079 } },
{ { 584000,1842079 }, { 582900,1841480 } },
{ { 582900,1841480 }, { 581020,1839899 } },
{ { 581020,1839899 }, { 579440,1838040 } },
{ { 579440,1838040 }, { 577840,1834299 } },
{ { 577840,1834299 }, { 576160,1831859 } },
{ { 576160,1831859 }, { 574540,1828499 } },
{ { 574540,1828499 }, { 572140,1822860 } },
{ { 572140,1822860 }, { 570180,1815219 } },
{ { 570180,1815219 }, { 570080,1812280 } },
{ { 570080,1812280 }, { 570340,1808300 } },
{ { 570340,1808300 }, { 570160,1807119 } },
{ { 570160,1807119 }, { 570140,1804039 } },
{ { 570140,1804039 }, { 571640,1796660 } },
{ { 571640,1796660 }, { 571740,1794680 } },
{ { 571740,1794680 }, { 572279,1794039 } },
{ { 572279,1794039 }, { 575480,1788300 } },
{ { 575480,1788300 }, { 576379,1787419 } },
{ { 576379,1787419 }, { 577020,1786120 } },
{ { 577020,1786120 }, { 578000,1785100 } },
{ { 578000,1785100 }, { 579960,1783720 } },
{ { 579960,1783720 }, { 581420,1782079 } },
{ { 581420,1782079 }, { 585480,1778440 } },
{ { 585480,1778440 }, { 586680,1777079 } },
{ { 586680,1777079 }, { 590520,1774639 } },
{ { 590520,1774639 }, { 592440,1773199 } },
{ { 592440,1773199 }, { 595160,1772260 } },
{ { 595160,1772260 }, { 598079,1770920 } },
{ { 598079,1770920 }, { 601420,1769019 } },
{ { 601420,1769019 }, { 606400,1767280 } },
{ { 606400,1767280 }, { 607320,1766620 } },
{ { 607320,1766620 }, { 605760,1766460 } },
{ { 605760,1766460 }, { 604420,1766780 } },
{ { 604420,1766780 }, { 601660,1766579 } },
{ { 601660,1766579 }, { 597160,1766980 } },
{ { 597160,1766980 }, { 591420,1766720 } },
{ { 591420,1766720 }, { 585360,1765460 } },
{ { 585360,1765460 }, { 578540,1763680 } },
{ { 578540,1763680 }, { 574020,1761599 } },
{ { 574020,1761599 }, { 572520,1760560 } },
{ { 572520,1760560 }, { 570959,1759000 } },
{ { 570959,1759000 }, { 566580,1755620 } },
{ { 566580,1755620 }, { 563820,1752000 } },
{ { 563820,1752000 }, { 563140,1751380 } },
{ { 563140,1751380 }, { 560800,1747899 } },
{ { 560800,1747899 }, { 558640,1742280 } },
{ { 558640,1742280 }, { 557860,1741620 } },
{ { 557860,1741620 }, { 555820,1739099 } },
{ { 555820,1739099 }, { 553920,1737540 } },
{ { 553920,1737540 }, { 551900,1735179 } },
{ { 551900,1735179 }, { 551180,1733880 } },
{ { 551180,1733880 }, { 549540,1729559 } },
{ { 549540,1729559 }, { 548860,1720720 } },
{ { 548860,1720720 }, { 549080,1719099 } },
{ { 549080,1719099 }, { 548200,1714700 } },
{ { 548200,1714700 }, { 547560,1713860 } },
{ { 547560,1713860 }, { 544500,1711259 } },
{ { 544500,1711259 }, { 543939,1709780 } },
{ { 543939,1709780 }, { 544520,1705439 } },
{ { 544520,1705439 }, { 543520,1701519 } },
{ { 543520,1701519 }, { 543920,1699319 } },
{ { 543920,1699319 }, { 546360,1697440 } },
{ { 546360,1697440 }, { 546680,1695419 } },
{ { 546680,1695419 }, { 545600,1694180 } },
{ { 545600,1694180 }, { 543220,1692000 } },
{ { 543220,1692000 }, { 538260,1685139 } },
{ { 538260,1685139 }, { 537540,1683000 } },
{ { 537540,1683000 }, { 537020,1682220 } },
{ { 537020,1682220 }, { 535560,1675940 } },
{ { 535560,1675940 }, { 535940,1671220 } },
{ { 535940,1671220 }, { 536320,1669379 } },
{ { 536320,1669379 }, { 535420,1666400 } },
{ { 535420,1666400 }, { 533540,1664460 } },
{ { 533540,1664460 }, { 530720,1662860 } },
{ { 530720,1662860 }, { 529240,1662260 } },
{ { 529240,1662260 }, { 528780,1659160 } },
{ { 528780,1659160 }, { 528820,1653560 } },
{ { 528820,1653560 }, { 529779,1650900 } },
{ { 529779,1650900 }, { 536760,1640840 } },
{ { 536760,1640840 }, { 540360,1636120 } },
{ { 540360,1636120 }, { 541160,1635380 } },
{ { 541160,1635380 }, { 544719,1629480 } },
{ { 544719,1629480 }, { 545319,1626140 } },
{ { 545319,1626140 }, { 543560,1623740 } },
{ { 543560,1623740 }, { 539880,1620739 } },
{ { 539880,1620739 }, { 533400,1617300 } },
{ { 533400,1617300 }, { 527840,1613020 } },
{ { 527840,1613020 }, { 525200,1611579 } },
{ { 525200,1611579 }, { 524360,1610800 } },
{ { 524360,1610800 }, { 517320,1605739 } },
{ { 517320,1605739 }, { 516240,1604240 } },
{ { 516240,1604240 }, { 515220,1602000 } },
{ { 515220,1602000 }, { 514079,1594240 } },
{ { 514079,1594240 }, { 513740,1581460 } },
{ { 513740,1581460 }, { 514660,1577359 } },
{ { 514660,1577359 }, { 514660,1576380 } },
{ { 514660,1576380 }, { 514199,1575380 } },
{ { 514199,1575380 }, { 514680,1572860 } },
{ { 514680,1572860 }, { 513440,1573940 } },
{ { 513440,1573940 }, { 512399,1575580 } },
{ { 512399,1575580 }, { 511620,1576220 } },
{ { 511620,1576220 }, { 507840,1581880 } },
{ { 507840,1581880 }, { 504600,1584579 } },
{ { 504600,1584579 }, { 502440,1584599 } },
{ { 502440,1584599 }, { 499060,1584059 } },
{ { 499060,1584059 }, { 498019,1581960 } },
{ { 498019,1581960 }, { 497819,1581240 } },
{ { 497819,1581240 }, { 498019,1576039 } },
{ { 498019,1576039 }, { 497539,1574740 } },
{ { 497539,1574740 }, { 495459,1574460 } },
{ { 495459,1574460 }, { 492320,1575600 } },
{ { 492320,1575600 }, { 491040,1576360 } },
{ { 491040,1576360 }, { 490080,1575640 } },
{ { 490080,1575640 }, { 490020,1575040 } },
{ { 490020,1575040 }, { 490220,1574400 } },
{ { 490220,1574400 }, { 490819,1573440 } },
{ { 490819,1573440 }, { 492680,1568259 } },
{ { 492680,1568259 }, { 492920,1566799 } },
{ { 492920,1566799 }, { 495760,1563660 } },
{ { 495760,1563660 }, { 496100,1562139 } },
{ { 496100,1562139 }, { 497879,1560240 } },
{ { 497879,1560240 }, { 497059,1558020 } },
{ { 497059,1558020 }, { 495620,1557399 } },
{ { 495620,1557399 }, { 494800,1556839 } },
{ { 494800,1556839 }, { 493500,1555479 } },
{ { 493500,1555479 }, { 491860,1554100 } },
{ { 491860,1554100 }, { 487840,1552139 } },
{ { 487840,1552139 }, { 485900,1551720 } },
{ { 485900,1551720 }, { 483639,1555439 } },
{ { 483639,1555439 }, { 482080,1556480 } },
{ { 482080,1556480 }, { 480200,1556259 } },
{ { 480200,1556259 }, { 478519,1556259 } },
{ { 478519,1556259 }, { 474020,1554019 } },
{ { 474020,1554019 }, { 472660,1551539 } },
{ { 472660,1551539 }, { 471260,1549899 } },
{ { 471260,1549899 }, { 470459,1548020 } },
{ { 470459,1548020 }, { 469920,1545479 } },
{ { 469920,1545479 }, { 469079,1542939 } },
{ { 469079,1542939 }, { 469120,1541799 } },
{ { 469120,1541799 }, { 465840,1537139 } },
{ { 465840,1537139 }, { 463360,1539059 } },
{ { 463360,1539059 }, { 459680,1546900 } },
{ { 459680,1546900 }, { 458439,1547160 } },
{ { 458439,1547160 }, { 456480,1549319 } },
{ { 456480,1549319 }, { 454160,1551400 } },
{ { 454160,1551400 }, { 452819,1550820 } },
{ { 452819,1550820 }, { 451699,1549839 } },
{ { 451699,1549839 }, { 449620,1548440 } },
{ { 449620,1548440 }, { 449419,1548080 } },
{ { 449419,1548080 }, { 447879,1547720 } },
{ { 447879,1547720 }, { 446540,1546819 } },
{ { 446540,1546819 }, { 445720,1545640 } },
{ { 445720,1545640 }, { 444800,1545100 } },
{ { 444800,1545100 }, { 443500,1542899 } },
{ { 443500,1542899 }, { 443320,1541799 } },
{ { 443320,1541799 }, { 443519,1540220 } },
{ { 443519,1540220 }, { 445060,1537099 } },
{ { 445060,1537099 }, { 445840,1533040 } },
{ { 445840,1533040 }, { 442720,1529079 } },
{ { 442720,1529079 }, { 442479,1528360 } },
{ { 442479,1528360 }, { 436820,1529240 } },
{ { 436820,1529240 }, { 436279,1529200 } },
{ { 436279,1529200 }, { 433280,1529859 } },
{ { 433280,1529859 }, { 420220,1529899 } },
{ { 420220,1529899 }, { 414740,1528539 } },
{ { 414740,1528539 }, { 411340,1527960 } },
{ { 411340,1527960 }, { 406860,1524660 } },
{ { 406860,1524660 }, { 405379,1523080 } },
{ { 405379,1523080 }, { 403639,1520320 } },
{ { 403639,1520320 }, { 402040,1517220 } },
{ { 402040,1517220 }, { 400519,1517059 } },
{ { 400519,1517059 }, { 399180,1516720 } },
{ { 399180,1516720 }, { 395300,1515179 } },
{ { 395300,1515179 }, { 394780,1515080 } },
{ { 394780,1515080 }, { 394759,1515900 } },
{ { 394759,1515900 }, { 394339,1516579 } },
{ { 394339,1516579 }, { 393200,1516640 } },
{ { 393200,1516640 }, { 392599,1521799 } },
{ { 392599,1521799 }, { 391699,1525200 } },
{ { 391699,1525200 }, { 391040,1525600 } },
{ { 391040,1525600 }, { 390540,1526500 } },
{ { 390540,1526500 }, { 388999,1527939 } },
{ { 388999,1527939 }, { 387059,1531100 } },
{ { 387059,1531100 }, { 386540,1531440 } },
{ { 386540,1531440 }, { 382140,1531839 } },
{ { 382140,1531839 }, { 377360,1532619 } },
{ { 377360,1532619 }, { 375640,1532220 } },
{ { 375640,1532220 }, { 372580,1531019 } },
{ { 372580,1531019 }, { 371079,1529019 } },
{ { 371079,1529019 }, { 367280,1526039 } },
{ { 367280,1526039 }, { 366460,1521900 } },
{ { 366460,1521900 }, { 364320,1516400 } },
{ { 364320,1516400 }, { 363779,1515780 } },
{ { 363779,1515780 }, { 362220,1515320 } },
{ { 362220,1515320 }, { 361979,1515060 } },
{ { 361979,1515060 }, { 360820,1515739 } },
{ { 360820,1515739 }, { 353360,1518620 } },
{ { 353360,1518620 }, { 347840,1520080 } },
{ { 347840,1520080 }, { 342399,1521140 } },
{ { 342399,1521140 }, { 334899,1523380 } },
{ { 334899,1523380 }, { 333220,1523400 } },
{ { 333220,1523400 }, { 332599,1522919 } },
{ { 332599,1522919 }, { 329780,1521640 } },
{ { 329780,1521640 }, { 325360,1521220 } },
{ { 325360,1521220 }, { 319000,1520999 } },
{ { 319000,1520999 }, { 316180,1520240 } },
{ { 316180,1520240 }, { 312700,1518960 } },
{ { 312700,1518960 }, { 310520,1517679 } },
{ { 310520,1517679 }, { 309280,1517260 } },
{ { 309280,1517260 }, { 306440,1515040 } },
{ { 306440,1515040 }, { 304140,1512780 } },
{ { 304140,1512780 }, { 301640,1509720 } },
{ { 301640,1509720 }, { 301500,1509879 } },
{ { 301500,1509879 }, { 300320,1509059 } },
{ { 300320,1509059 }, { 299140,1507339 } },
{ { 299140,1507339 }, { 297340,1502659 } },
{ { 297340,1502659 }, { 298960,1508280 } },
{ { 298960,1508280 }, { 299120,1509299 } },
{ { 299120,1509299 }, { 298720,1510100 } },
{ { 298720,1510100 }, { 298420,1512240 } },
{ { 298420,1512240 }, { 297420,1514540 } },
{ { 297420,1514540 }, { 296900,1515340 } },
{ { 296900,1515340 }, { 294780,1517500 } },
{ { 294780,1517500 }, { 293040,1518380 } },
{ { 293040,1518380 }, { 289140,1521360 } },
{ { 289140,1521360 }, { 283600,1523300 } },
{ { 283600,1523300 }, { 280140,1525220 } },
{ { 280140,1525220 }, { 279620,1525679 } },
{ { 279620,1525679 }, { 274960,1527379 } },
{ { 274960,1527379 }, { 273440,1528819 } },
{ { 273440,1528819 }, { 269840,1532840 } },
{ { 269840,1532840 }, { 264800,1536240 } },
{ { 264800,1536240 }, { 261199,1540419 } },
{ { 261199,1540419 }, { 257359,1541400 } },
{ { 257359,1541400 }, { 250460,1539299 } },
{ { 250460,1539299 }, { 250240,1539400 } },
{ { 250240,1539400 }, { 249840,1540460 } },
{ { 249840,1540460 }, { 249779,1541140 } },
{ { 249779,1541140 }, { 248482,1539783 } },
{ { 248482,1539783 }, { 251320,1544120 } },
{ { 251320,1544120 }, { 252500,1548320 } },
{ { 252500,1548320 }, { 252519,1549740 } },
{ { 252519,1549740 }, { 253000,1553140 } },
{ { 253000,1553140 }, { 252920,1556539 } },
{ { 252920,1556539 }, { 253160,1556700 } },
{ { 253160,1556700 }, { 254019,1558220 } },
{ { 254019,1558220 }, { 253039,1559339 } },
{ { 253039,1559339 }, { 252300,1561920 } },
{ { 252300,1561920 }, { 251080,1565260 } },
{ { 251080,1565260 }, { 251120,1566160 } },
{ { 251120,1566160 }, { 249979,1570240 } },
{ { 249979,1570240 }, { 248799,1575380 } },
{ { 248799,1575380 }, { 247180,1579520 } },
{ { 247180,1579520 }, { 243380,1588440 } },
{ { 243380,1588440 }, { 241700,1591780 } },
{ { 241700,1591780 }, { 240280,1593080 } },
{ { 240280,1593080 }, { 231859,1598380 } },
{ { 231859,1598380 }, { 228840,1600060 } },
{ { 228840,1600060 }, { 226420,1601080 } },
{ { 226420,1601080 }, { 223620,1601940 } },
{ { 223620,1601940 }, { 220919,1603819 } },
{ { 220919,1603819 }, { 219599,1604420 } },
{ { 219599,1604420 }, { 218380,1605200 } },
{ { 218380,1605200 }, { 213219,1607260 } },
{ { 213219,1607260 }, { 210040,1607740 } },
{ { 210040,1607740 }, { 186439,1596440 } },
{ { 186439,1596440 }, { 185159,1594559 } },
{ { 185159,1594559 }, { 182239,1588300 } },
{ { 182239,1588300 }, { 181040,1585380 } },
{ { 181040,1585380 }, { 180380,1578580 } },
{ { 180380,1578580 }, { 180679,1573220 } },
{ { 180679,1573220 }, { 181220,1568539 } },
{ { 181220,1568539 }, { 181859,1565020 } },
{ { 181859,1565020 }, { 184499,1555500 } },
{ { 184499,1555500 }, { 183480,1558160 } },
{ { 183480,1558160 }, { 182600,1561700 } },
{ { 182600,1561700 }, { 171700,1554359 } },
{ { 171700,1554359 }, { 176880,1545920 } },
{ { 176880,1545920 }, { 189940,1529000 } },
{ { 189940,1529000 }, { 200040,1535759 } },
{ { 200040,1535759 }, { 207559,1531660 } },
{ { 207559,1531660 }, { 218039,1527520 } },
{ { 218039,1527520 }, { 222360,1526640 } },
{ { 222360,1526640 }, { 225439,1526440 } },
{ { 225439,1526440 }, { 231160,1527079 } },
{ { 231160,1527079 }, { 232300,1527399 } },
{ { 232300,1527399 }, { 236579,1529140 } },
{ { 236579,1529140 }, { 238139,1529120 } },
{ { 238139,1529120 }, { 238799,1529319 } },
{ { 238799,1529319 }, { 240999,1531780 } },
{ { 240999,1531780 }, { 238280,1528799 } },
{ { 238280,1528799 }, { 236900,1523840 } },
{ { 236900,1523840 }, { 236800,1522700 } },
{ { 236800,1522700 }, { 235919,1518880 } },
{ { 235919,1518880 }, { 236080,1514299 } },
{ { 236080,1514299 }, { 238260,1508380 } },
{ { 238260,1508380 }, { 240119,1505159 } },
{ { 240119,1505159 }, { 233319,1496360 } },
{ { 233319,1496360 }, { 239140,1490759 } },
{ { 239140,1490759 }, { 258760,1478080 } },
{ { 258760,1478080 }, { 263940,1484760 } },
{ { 263940,1484760 }, { 263460,1485159 } },
{ { 263460,1485159 }, { 265960,1483519 } },
{ { 265960,1483519 }, { 270380,1482020 } },
{ { 270380,1482020 }, { 272880,1481420 } },
{ { 272880,1481420 }, { 275700,1481400 } },
{ { 275700,1481400 }, { 278380,1481740 } },
{ { 278380,1481740 }, { 281220,1482979 } },
{ { 281220,1482979 }, { 284680,1484859 } },
{ { 284680,1484859 }, { 285979,1486140 } },
{ { 285979,1486140 }, { 290220,1489100 } },
{ { 290220,1489100 }, { 292680,1489520 } },
{ { 292680,1489520 }, { 293280,1490240 } },
{ { 293280,1490240 }, { 293140,1489160 } },
{ { 293140,1489160 }, { 293280,1488580 } },
{ { 293280,1488580 }, { 294100,1486980 } },
{ { 294100,1486980 }, { 294580,1484960 } },
{ { 294580,1484960 }, { 295680,1481660 } },
{ { 295680,1481660 }, { 297840,1477339 } },
{ { 297840,1477339 }, { 302240,1472280 } },
{ { 302240,1472280 }, { 307120,1469000 } },
{ { 307120,1469000 }, { 314500,1466340 } },
{ { 314500,1466340 }, { 324979,1464740 } },
{ { 324979,1464740 }, { 338999,1462059 } },
{ { 338999,1462059 }, { 345599,1461579 } },
{ { 345599,1461579 }, { 349020,1461620 } },
{ { 349020,1461620 }, { 353420,1461160 } },
{ { 353420,1461160 }, { 357000,1461500 } },
{ { 357000,1461500 }, { 359860,1461579 } },
{ { 359860,1461579 }, { 364520,1462740 } },
{ { 364520,1462740 }, { 367280,1464000 } },
{ { 367280,1464000 }, { 372020,1467560 } },
{ { 372020,1467560 }, { 373999,1469980 } },
{ { 373999,1469980 }, { 375580,1472240 } },
{ { 375580,1472240 }, { 376680,1474460 } },
{ { 376680,1474460 }, { 377259,1478620 } },
{ { 377259,1478620 }, { 379279,1480880 } },
{ { 379279,1480880 }, { 379260,1481600 } },
{ { 379260,1481600 }, { 378760,1482000 } },
{ { 378760,1482000 }, { 379300,1482040 } },
{ { 379300,1482040 }, { 380220,1482460 } },
{ { 380220,1482460 }, { 380840,1483020 } },
{ { 380840,1483020 }, { 385519,1482600 } },
{ { 385519,1482600 }, { 386019,1482320 } },
{ { 386019,1482320 }, { 386499,1481600 } },
{ { 386499,1481600 }, { 386540,1480139 } },
{ { 386540,1480139 }, { 387500,1478220 } },
{ { 387500,1478220 }, { 388280,1476100 } },
{ { 388280,1476100 }, { 390060,1473000 } },
{ { 390060,1473000 }, { 393659,1469460 } },
{ { 393659,1469460 }, { 396540,1467860 } },
{ { 396540,1467860 }, { 401260,1466040 } },
{ { 401260,1466040 }, { 406200,1465100 } },
{ { 406200,1465100 }, { 410920,1465439 } },
{ { 410920,1465439 }, { 420659,1467399 } },
{ { 420659,1467399 }, { 433500,1471480 } },
{ { 433500,1471480 }, { 441340,1473540 } },
{ { 441340,1473540 }, { 448620,1475139 } },
{ { 448620,1475139 }, { 450720,1475880 } },
{ { 450720,1475880 }, { 453299,1477059 } },
{ { 453299,1477059 }, { 456620,1478940 } },
{ { 456620,1478940 }, { 458480,1480399 } },
{ { 458480,1480399 }, { 461100,1482780 } },
{ { 461100,1482780 }, { 463820,1486519 } },
{ { 463820,1486519 }, { 464780,1488199 } },
{ { 464780,1488199 }, { 466579,1493960 } },
{ { 466579,1493960 }, { 467120,1497700 } },
{ { 467120,1497700 }, { 466999,1500280 } },
{ { 466999,1500280 }, { 467300,1502580 } },
{ { 467300,1502580 }, { 467399,1505280 } },
{ { 467399,1505280 }, { 466979,1506920 } },
{ { 466979,1506920 }, { 467920,1504780 } },
{ { 467920,1504780 }, { 468159,1505040 } },
{ { 468159,1505040 }, { 469400,1504859 } },
{ { 469400,1504859 }, { 470300,1505540 } },
{ { 470300,1505540 }, { 471240,1505200 } },
{ { 471240,1505200 }, { 471579,1504280 } },
{ { 471579,1504280 }, { 473939,1502379 } },
{ { 473939,1502379 }, { 476860,1500200 } },
{ { 476860,1500200 }, { 479800,1498620 } },
{ { 479800,1498620 }, { 480840,1498120 } },
{ { 480840,1498120 }, { 485220,1497480 } },
{ { 485220,1497480 }, { 489979,1497460 } },
{ { 489979,1497460 }, { 494899,1498700 } },
{ { 494899,1498700 }, { 500099,1501320 } },
{ { 500099,1501320 }, { 501439,1501839 } },
{ { 501439,1501839 }, { 503400,1502939 } },
{ { 503400,1502939 }, { 510760,1508340 } },
{ { 510760,1508340 }, { 513640,1510920 } },
{ { 513640,1510920 }, { 518579,1514599 } },
{ { 518579,1514599 }, { 519020,1515260 } },
{ { 519020,1515260 }, { 520700,1516480 } },
{ { 520700,1516480 }, { 524960,1521480 } },
{ { 524960,1521480 }, { 526820,1524820 } },
{ { 526820,1524820 }, { 528280,1527820 } },
{ { 528280,1527820 }, { 529120,1533120 } },
{ { 529120,1533120 }, { 528820,1537139 } },
{ { 528820,1537139 }, { 527020,1543920 } },
{ { 527020,1543920 }, { 526959,1546780 } },
{ { 526959,1546780 }, { 526420,1548060 } },
{ { 526420,1548060 }, { 527020,1547919 } },
{ { 527020,1547919 }, { 527620,1548160 } },
{ { 527620,1548160 }, { 528980,1548020 } },
{ { 528980,1548020 }, { 535180,1544980 } },
{ { 535180,1544980 }, { 540860,1542979 } },
{ { 540860,1542979 }, { 546480,1542720 } },
{ { 546480,1542720 }, { 547420,1542860 } },
{ { 547420,1542860 }, { 551800,1544140 } },
{ { 551800,1544140 }, { 558740,1547939 } },
{ { 558740,1547939 }, { 569920,1556259 } },
{ { 569920,1556259 }, { 573660,1560220 } },
{ { 573660,1560220 }, { 573040,1559500 } },
{ { 573040,1559500 }, { 574740,1559220 } },
{ { 574740,1559220 }, { 588480,1562899 } },
{ { 588480,1562899 }, { 585180,1576019 } },
{ { 585180,1576019 }, { 583440,1577979 } },
{ { 583440,1577979 }, { 584280,1582399 } },
{ { 584280,1582399 }, { 584520,1588960 } },
{ { 584520,1588960 }, { 583420,1601620 } },
{ { 583420,1601620 }, { 582840,1603880 } },
{ { 582840,1603880 }, { 579860,1611400 } },
{ { 579860,1611400 }, { 577980,1614579 } },
{ { 577980,1614579 }, { 577380,1616080 } },
{ { 577380,1616080 }, { 563800,1621579 } },
{ { 563800,1621579 }, { 561320,1622320 } },
{ { 561320,1622320 }, { 565080,1621960 } },
{ { 565080,1621960 }, { 571680,1620780 } },
{ { 571680,1620780 }, { 583260,1628340 } },
{ { 583260,1628340 }, { 583100,1630399 } },
{ { 583100,1630399 }, { 582200,1632160 } },
{ { 582200,1632160 }, { 595380,1627020 } },
{ { 595380,1627020 }, { 597400,1627320 } },
{ { 597400,1627320 }, { 602240,1628459 } },
{ { 602240,1628459 }, { 605660,1630260 } },
{ { 605660,1630260 }, { 610319,1634140 } },
{ { 610319,1634140 }, { 612340,1636319 } },
{ { 612340,1636319 }, { 614820,1638020 } },
{ { 614820,1638020 }, { 616460,1638740 } },
{ { 616460,1638740 }, { 620420,1639500 } },
{ { 620420,1639500 }, { 623000,1639280 } },
{ { 623000,1639280 }, { 624459,1639359 } },
{ { 624459,1639359 }, { 626180,1640159 } },
{ { 626180,1640159 }, { 627279,1640940 } },
{ { 627279,1640940 }, { 629980,1643759 } },
{ { 629980,1643759 }, { 632380,1648000 } },
{ { 632380,1648000 }, { 635020,1654800 } },
{ { 635020,1654800 }, { 636320,1659140 } },
{ { 636320,1659140 }, { 636680,1663620 } },
{ { 636680,1663620 }, { 636180,1665780 } },
{ { 636180,1665780 }, { 630620,1669720 } },
{ { 630620,1669720 }, { 628760,1672979 } },
{ { 628760,1672979 }, { 627540,1676859 } },
{ { 627540,1676859 }, { 627040,1680699 } },
{ { 627040,1680699 }, { 624700,1686500 } },
{ { 624700,1686500 }, { 623260,1688799 } },
{ { 623260,1688799 }, { 619620,1693799 } },
{ { 619620,1693799 }, { 621720,1694859 } },
{ { 621720,1694859 }, { 624940,1694379 } },
{ { 624940,1694379 }, { 627120,1695600 } },
{ { 627120,1695600 }, { 627740,1696120 } },
{ { 627740,1696120 }, { 631120,1697460 } },
{ { 631120,1697460 }, { 633980,1698340 } },
{ { 633980,1698340 }, { 638380,1700460 } },
{ { 638380,1700460 }, { 642660,1703300 } },
{ { 642660,1703300 }, { 643620,1704140 } },
{ { 643620,1704140 }, { 646300,1707000 } },
{ { 646300,1707000 }, { 649060,1710880 } },
{ { 649060,1710880 }, { 651160,1714879 } },
{ { 651160,1714879 }, { 651740,1716559 } },
{ { 651740,1716559 }, { 653139,1722619 } },
{ { 653139,1722619 }, { 653020,1728320 } },
{ { 653020,1728320 }, { 652719,1731420 } },
{ { 652719,1731420 }, { 651619,1736360 } },
{ { 651619,1736360 }, { 649819,1743160 } },
{ { 649819,1743160 }, { 646440,1749059 } },
{ { 646440,1749059 }, { 645219,1750399 } },
{ { 645219,1750399 }, { 643959,1752679 } },
{ { 643959,1752679 }, { 643959,1753740 } },
{ { 643959,1753740 }, { 642140,1754240 } },
{ { 642140,1754240 }, { 643760,1754099 } },
{ { 643760,1754099 }, { 644320,1754280 } },
{ { 644320,1754280 }, { 645000,1754879 } },
{ { 645000,1754879 }, { 646940,1755620 } },
{ { 646940,1755620 }, { 654779,1757820 } },
{ { 654779,1757820 }, { 661100,1761559 } },
{ { 661100,1761559 }, { 664099,1763980 } },
{ { 664099,1763980 }, { 668220,1768480 } },
{ { 668220,1768480 }, { 671920,1773640 } },
{ { 671920,1773640 }, { 674939,1779540 } },
{ { 674939,1779540 }, { 677760,1782440 } },
{ { 677760,1782440 }, { 679080,1785739 } },
{ { 679080,1785739 }, { 678780,1788100 } },
{ { 678780,1788100 }, { 678020,1791500 } },
{ { 678020,1791500 }, { 677120,1793600 } },
{ { 677120,1793600 }, { 676860,1795800 } },
{ { 676860,1795800 }, { 676440,1797320 } },
{ { 676440,1797320 }, { 676459,1798519 } },
{ { 676459,1798519 }, { 675620,1800159 } },
{ { 675620,1800159 }, { 675520,1801019 } },
{ { 675520,1801019 }, { 673360,1804899 } },
{ { 673360,1804899 }, { 672740,1807079 } },
{ { 672740,1807079 }, { 673300,1809260 } },
{ { 673300,1809260 }, { 674539,1811019 } },
{ { 674539,1811019 }, { 675499,1812020 } },
{ { 675499,1812020 }, { 677660,1817240 } },
{ { 677660,1817240 }, { 679659,1824280 } },
{ { 679659,1824280 }, { 680380,1828779 } },
{ { 680380,1828779 }, { 679519,1837999 } },
{ { 679519,1837999 }, { 677940,1844379 } },
{ { 677940,1844379 }, { 676940,1846900 } },
{ { 676940,1846900 }, { 675479,1849379 } },
{ { 675479,1849379 }, { 674000,1851200 } },
{ { 674000,1851200 }, { 671380,1853480 } },
{ { 671380,1853480 }, { 667019,1855240 } },
{ { 667019,1855240 }, { 662540,1856060 } },
{ { 662540,1856060 }, { 660960,1856599 } },
{ { 660960,1856599 }, { 656240,1857020 } },
{ { 656240,1857020 }, { 655600,1856960 } },
{ { 655600,1856960 }, { 652839,1855880 } },
{ { 652839,1855880 }, { 652019,1855840 } },
{ { 652019,1855840 }, { 651459,1855060 } },
{ { 651459,1855060 }, { 652179,1854359 } },
{ { 652179,1854359 }, { 652019,1849919 } },
{ { 652019,1849919 }, { 650620,1846920 } },
{ { 650620,1846920 }, { 647299,1844540 } },
{ { 647299,1844540 }, { 644500,1843819 } },
{ { 644500,1843819 }, { 641860,1844859 } },
{ { 641860,1844859 }, { 641059,1845340 } },
{ { 641059,1845340 }, { 638860,1845820 } },
{ { 638860,1845820 }, { 638000,1845820 } },
{ { 638000,1845820 }, { 636340,1845479 } },
{ { 636340,1845479 }, { 634980,1844800 } },
{ { 634980,1844800 }, { 632660,1842979 } },
{ { 632660,1842979 }, { 631140,1841120 } },
{ { 631140,1841120 }, { 629140,1839520 } },
{ { 629140,1839520 }, { 626640,1839540 } },
{ { 626640,1839540 }, { 624159,1840739 } },
{ { 624159,1840739 }, { 623820,1841380 } },
{ { 623820,1841380 }, { 622440,1842719 } },
{ { 622440,1842719 }, { 622100,1843680 } },
{ { 622100,1843680 }, { 623780,1846100 } },
{ { 623780,1846100 }, { 624580,1846920 } },
{ { 624580,1846920 }, { 626120,1856720 } },
{ { 626120,1856720 }, { 627440,1860000 } },
{ { 627440,1860000 }, { 628000,1864299 } },
{ { 628000,1864299 }, { 627380,1865999 } },
{ { 627380,1865999 }, { 626260,1867580 } },
{ { 626260,1867580 }, { 623660,1869520 } },
{ { 623660,1869520 }, { 618680,1872780 } },
{ { 618680,1872780 }, { 617699,1873140 } },
{ { 617699,1873140 }, { 612000,1874160 } },
{ { 612000,1874160 }, { 609840,1874220 } },
{ { 609840,1874220 }, { 606940,1873860 } },
{ { 136680,1926960 }, { 135500,1926360 } },
{ { 135500,1926360 }, { 137360,1923060 } },
{ { 137360,1923060 }, { 139500,1918559 } },
{ { 139500,1918559 }, { 140780,1913239 } },
{ { 140780,1913239 }, { 139600,1913020 } },
{ { 139600,1913020 }, { 127380,1923600 } },
{ { 127380,1923600 }, { 122800,1926059 } },
{ { 122800,1926059 }, { 118879,1927719 } },
{ { 118879,1927719 }, { 114420,1928300 } },
{ { 114420,1928300 }, { 111480,1927020 } },
{ { 111480,1927020 }, { 110619,1925399 } },
{ { 110619,1925399 }, { 109620,1924200 } },
{ { 109620,1924200 }, { 108860,1922780 } },
{ { 108860,1922780 }, { 108479,1920999 } },
{ { 108479,1920999 }, { 106600,1918080 } },
{ { 106600,1918080 }, { 106220,1917740 } },
{ { 106220,1917740 }, { 105199,1916960 } },
{ { 105199,1916960 }, { 101460,1914859 } },
{ { 101460,1914859 }, { 99480,1914379 } },
{ { 99480,1914379 }, { 97179,1913499 } },
{ { 97179,1913499 }, { 94900,1911100 } },
{ { 94900,1911100 }, { 94100,1909639 } },
{ { 94100,1909639 }, { 93379,1907740 } },
{ { 93379,1907740 }, { 93960,1898259 } },
{ { 93960,1898259 }, { 93739,1896460 } },
{ { 93739,1896460 }, { 94299,1893080 } },
{ { 94299,1893080 }, { 97240,1883440 } },
{ { 97240,1883440 }, { 99799,1879780 } },
{ { 99799,1879780 }, { 100400,1878120 } },
{ { 100400,1878120 }, { 100199,1877200 } },
{ { 100199,1877200 }, { 98940,1877460 } },
{ { 98940,1877460 }, { 96320,1878480 } },
{ { 96320,1878480 }, { 86020,1881039 } },
{ { 86020,1881039 }, { 84340,1881080 } },
{ { 84340,1881080 }, { 76780,1882600 } },
{ { 76780,1882600 }, { 74380,1883580 } },
{ { 74380,1883580 }, { 72679,1884019 } },
{ { 72679,1884019 }, { 70900,1885940 } },
{ { 70900,1885940 }, { 71240,1888340 } },
{ { 71240,1888340 }, { 72720,1889940 } },
{ { 72720,1889940 }, { 74640,1891360 } },
{ { 74640,1891360 }, { 75620,1893179 } },
{ { 75620,1893179 }, { 77140,1895340 } },
{ { 77140,1895340 }, { 81040,1899500 } },
{ { 81040,1899500 }, { 82760,1900380 } },
{ { 82760,1900380 }, { 83720,1902300 } },
{ { 83720,1902300 }, { 85459,1903700 } },
{ { 85459,1903700 }, { 86960,1905940 } },
{ { 86960,1905940 }, { 88280,1913020 } },
{ { 88280,1913020 }, { 88160,1913539 } },
{ { 88160,1913539 }, { 88020,1913860 } },
{ { 88020,1913860 }, { 86080,1915200 } },
{ { 86080,1915200 }, { 85660,1916740 } },
{ { 85660,1916740 }, { 83899,1918799 } },
{ { 83899,1918799 }, { 79360,1921160 } },
{ { 79360,1921160 }, { 76400,1923140 } },
{ { 76400,1923140 }, { 70800,1926180 } },
{ { 70800,1926180 }, { 64460,1927659 } },
{ { 64460,1927659 }, { 60880,1927820 } },
{ { 60880,1927820 }, { 55780,1925580 } },
{ { 55780,1925580 }, { 54940,1925040 } },
{ { 54940,1925040 }, { 52199,1921700 } },
{ { 52199,1921700 }, { 49680,1916579 } },
{ { 49680,1916579 }, { 48719,1914180 } },
{ { 48719,1914180 }, { 48620,1913080 } },
{ { 48620,1913080 }, { 47640,1909120 } },
{ { 47640,1909120 }, { 48280,1899319 } },
{ { 48280,1899319 }, { 49140,1895600 } },
{ { 49140,1895600 }, { 50320,1892899 } },
{ { 50320,1892899 }, { 51559,1890640 } },
{ { 51559,1890640 }, { 52140,1889960 } },
{ { 52140,1889960 }, { 54640,1887999 } },
{ { 54640,1887999 }, { 55639,1886500 } },
{ { 55639,1886500 }, { 55720,1885080 } },
{ { 55720,1885080 }, { 55439,1883220 } },
{ { 55439,1883220 }, { 54640,1882159 } },
{ { 54640,1882159 }, { 54100,1880300 } },
{ { 54100,1880300 }, { 52479,1874079 } },
{ { 52479,1874079 }, { 51700,1869000 } },
{ { 51700,1869000 }, { 51600,1865419 } },
{ { 51600,1865419 }, { 51720,1859820 } },
{ { 51720,1859820 }, { 52160,1857260 } },
{ { 52160,1857260 }, { 52539,1856120 } },
{ { 52539,1856120 }, { 57240,1845720 } },
{ { 57240,1845720 }, { 58280,1844400 } },
{ { 58280,1844400 }, { 60639,1840820 } },
{ { 60639,1840820 }, { 65580,1835540 } },
{ { 65580,1835540 }, { 68340,1833340 } },
{ { 68340,1833340 }, { 71660,1831480 } },
{ { 71660,1831480 }, { 73460,1829960 } },
{ { 73460,1829960 }, { 75200,1829319 } },
{ { 75200,1829319 }, { 77200,1828960 } },
{ { 77200,1828960 }, { 78640,1828920 } },
{ { 78640,1828920 }, { 111780,1842700 } },
{ { 111780,1842700 }, { 112800,1843480 } },
{ { 112800,1843480 }, { 113879,1844879 } },
{ { 113879,1844879 }, { 116379,1847379 } },
{ { 116379,1847379 }, { 116360,1847580 } },
{ { 116360,1847580 }, { 117100,1848799 } },
{ { 117100,1848799 }, { 120160,1851799 } },
{ { 120160,1851799 }, { 121860,1852320 } },
{ { 121860,1852320 }, { 124280,1852679 } },
{ { 124280,1852679 }, { 128920,1854659 } },
{ { 128920,1854659 }, { 130840,1856360 } },
{ { 130840,1856360 }, { 133520,1859460 } },
{ { 133520,1859460 }, { 135079,1860860 } },
{ { 135079,1860860 }, { 137280,1864440 } },
{ { 137280,1864440 }, { 142980,1872899 } },
{ { 142980,1872899 }, { 144600,1875840 } },
{ { 144600,1875840 }, { 147240,1883480 } },
{ { 147240,1883480 }, { 147460,1886539 } },
{ { 147460,1886539 }, { 147660,1886920 } },
{ { 147660,1886920 }, { 148399,1891720 } },
{ { 148399,1891720 }, { 148820,1896799 } },
{ { 148820,1896799 }, { 148399,1898880 } },
{ { 148399,1898880 }, { 148799,1899420 } },
{ { 148799,1899420 }, { 150520,1898539 } },
{ { 150520,1898539 }, { 154760,1892760 } },
{ { 154760,1892760 }, { 156580,1889240 } },
{ { 156580,1889240 }, { 156940,1888900 } },
{ { 156940,1888900 }, { 157540,1889540 } },
{ { 157540,1889540 }, { 156860,1896819 } },
{ { 156860,1896819 }, { 155639,1903940 } },
{ { 155639,1903940 }, { 153679,1908100 } },
{ { 153679,1908100 }, { 152859,1909039 } },
{ { 152859,1909039 }, { 149660,1915580 } },
{ { 149660,1915580 }, { 148000,1918600 } },
{ { 148000,1918600 }, { 141640,1926980 } },
{ { 141640,1926980 }, { 140060,1927899 } },
{ { 140060,1927899 }, { 136960,1929019 } },
{ { 136960,1929019 }, { 136680,1926960 } },
{ { 627100,1941519 }, { 625120,1940060 } },
{ { 625120,1940060 }, { 614580,1934680 } },
{ { 614580,1934680 }, { 608780,1929319 } },
{ { 608780,1929319 }, { 607400,1927679 } },
{ { 607400,1927679 }, { 606160,1925920 } },
{ { 606160,1925920 }, { 604480,1922240 } },
{ { 604480,1922240 }, { 602420,1916819 } },
{ { 602420,1916819 }, { 602279,1915260 } },
{ { 602279,1915260 }, { 602880,1907960 } },
{ { 602880,1907960 }, { 604140,1902719 } },
{ { 604140,1902719 }, { 605880,1898539 } },
{ { 605880,1898539 }, { 606640,1897399 } },
{ { 606640,1897399 }, { 609680,1894420 } },
{ { 609680,1894420 }, { 611099,1893640 } },
{ { 611099,1893640 }, { 616099,1890340 } },
{ { 616099,1890340 }, { 617520,1889160 } },
{ { 617520,1889160 }, { 620220,1885540 } },
{ { 620220,1885540 }, { 624480,1882260 } },
{ { 624480,1882260 }, { 628660,1880280 } },
{ { 628660,1880280 }, { 632520,1879659 } },
{ { 632520,1879659 }, { 637760,1879859 } },
{ { 637760,1879859 }, { 640899,1881500 } },
{ { 640899,1881500 }, { 644220,1883980 } },
{ { 644220,1883980 }, { 643900,1890860 } },
{ { 643900,1890860 }, { 643060,1894160 } },
{ { 643060,1894160 }, { 642459,1900320 } },
{ { 642459,1900320 }, { 642400,1903120 } },
{ { 642400,1903120 }, { 643819,1908519 } },
{ { 643819,1908519 }, { 644700,1912560 } },
{ { 644700,1912560 }, { 644640,1916380 } },
{ { 644640,1916380 }, { 644959,1918600 } },
{ { 644959,1918600 }, { 642540,1925620 } },
{ { 642540,1925620 }, { 642439,1926640 } },
{ { 642439,1926640 }, { 641860,1928300 } },
{ { 641860,1928300 }, { 638700,1932939 } },
{ { 638700,1932939 }, { 634820,1934200 } },
{ { 634820,1934200 }, { 631980,1936539 } },
{ { 631980,1936539 }, { 630160,1940600 } },
{ { 630160,1940600 }, { 627740,1941640 } },
{ { 627740,1941640 }, { 627400,1941660 } },
{ { 627400,1941660 }, { 627100,1941519 } }
};
#if 0
// Verify whether two any two non-neighbor line segments intersect. They should not, otherwise the Voronoi builder
// is not guaranteed to succeed.
for (size_t i = 0; i < lines.size(); ++ i)
for (size_t j = i + 1; j < lines.size(); ++ j) {
Point &ip1 = lines[i].a;
Point &ip2 = lines[i].b;
Point &jp1 = lines[j].a;
Point &jp2 = lines[j].b;
if (&ip1 != &jp2 && &jp1 != &ip2) {
REQUIRE(! Slic3r::Geometry::segments_intersect(ip1, ip2, jp1, jp2));
}
}
#endif
BoostVD vd;
construct_voronoi(lines.begin(), lines.end(), &vd);
for (const auto& edge : vd.edges())
if (edge.is_finite()) {
auto v0 = edge.vertex0();
auto v1 = edge.vertex1();
REQUIRE((v0->x() == 0 || std::isnormal(v0->x())));
REQUIRE((v0->y() == 0 || std::isnormal(v0->y())));
REQUIRE((v1->x() == 0 || std::isnormal(v1->x())));
REQUIRE((v1->y() == 0 || std::isnormal(v1->y())));
}
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-NaNs.svg").c_str(),
vd, Points(), lines, Polygons(), Lines(), 0.015);
#endif
}
struct OffsetTest {
double distance;
size_t num_outer;
size_t num_inner;
};
TEST_CASE("Voronoi offset", "[VoronoiOffset]")
{
Polygons poly_with_hole = { Polygon {
{ 0, 10000000},
{ 700000, 0},
{ 700000, 9000000},
{ 9100000, 9000000},
{ 9100000, 0},
{10000000, 10000000}
}
};
double area = std::accumulate(poly_with_hole.begin(), poly_with_hole.end(), 0., [](double a, auto &poly){ return a + poly.area(); });
REQUIRE(area > 0.);
VD vd;
Lines lines = to_lines(poly_with_hole);
vd.construct_voronoi(lines.begin(), lines.end());
for (const OffsetTest &ot : {
OffsetTest { scale_(0.2), 1, 1 },
OffsetTest { scale_(0.4), 1, 1 },
OffsetTest { scale_(0.5), 1, 2 },
OffsetTest { scale_(0.505), 1, 2 },
OffsetTest { scale_(0.51), 1, 2 },
OffsetTest { scale_(0.52), 1, 1 },
OffsetTest { scale_(0.53), 1, 1 },
OffsetTest { scale_(0.54), 1, 1 },
OffsetTest { scale_(0.55), 1, 0 }
}) {
#if 0
Polygons offsetted_polygons_out = Slic3r::Voronoi::offset(vd, lines, ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset-out-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_out);
#endif
REQUIRE(offsetted_polygons_out.size() == ot.num_outer);
#endif
Polygons offsetted_polygons_in = Slic3r::Voronoi::offset(vd, lines, - ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset-in-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_in);
#endif
REQUIRE(offsetted_polygons_in.size() == ot.num_inner);
}
}
TEST_CASE("Voronoi offset 2", "[VoronoiOffset]")
{
coord_t mm = coord_t(scale_(1.));
Polygons poly = {
Polygon {
{ 0, 0 },
{ 1, 0 },
{ 1, 1 },
{ 2, 1 },
{ 2, 0 },
{ 3, 0 },
{ 3, 2 },
{ 0, 2 }
},
Polygon {
{ 0, - 1 - 2 },
{ 3, - 1 - 2 },
{ 3, - 1 - 0 },
{ 2, - 1 - 0 },
{ 2, - 1 - 1 },
{ 1, - 1 - 1 },
{ 1, - 1 - 0 },
{ 0, - 1 - 0 }
},
};
for (Polygon &p : poly)
for (Point &pt : p.points)
pt *= mm;
double area = std::accumulate(poly.begin(), poly.end(), 0., [](double a, auto &poly){ return a + poly.area(); });
REQUIRE(area > 0.);
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
for (const OffsetTest &ot : {
OffsetTest { scale_(0.2), 2, 2 },
OffsetTest { scale_(0.4), 2, 2 },
OffsetTest { scale_(0.45), 2, 2 },
OffsetTest { scale_(0.48), 2, 2 },
OffsetTest { scale_(0.5), 2, 4 },
OffsetTest { scale_(0.505), 2, 4 },
OffsetTest { scale_(0.7), 2, 0 },
OffsetTest { scale_(0.8), 1, 0 }
}) {
Polygons offsetted_polygons_out = Slic3r::Voronoi::offset(vd, lines, ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset2-out-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_out);
#endif
REQUIRE(offsetted_polygons_out.size() == ot.num_outer);
Polygons offsetted_polygons_in = Slic3r::Voronoi::offset(vd, lines, - ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset2-in-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_in);
#endif
REQUIRE(offsetted_polygons_in.size() == ot.num_inner);
}
}
TEST_CASE("Voronoi offset 3", "[VoronoiOffset]")
{
coord_t mm = coord_t(scale_(1.));
Polygons poly = {
Polygon {
{ 0, 0 },
{ 2, 0 },
{ 2, 1 },
{ 3, 1 },
{ 3, 0 },
{ 5, 0 },
{ 5, 2 },
{ 4, 2 },
{ 4, 3 },
{ 1, 3 },
{ 1, 2 },
{ 0, 2 }
},
Polygon {
{ 0, -1 - 2 },
{ 1, -1 - 2 },
{ 1, -1 - 3 },
{ 4, -1 - 3 },
{ 4, -1 - 2 },
{ 5, -1 - 2 },
{ 5, -1 - 0 },
{ 3, -1 - 0 },
{ 3, -1 - 1 },
{ 2, -1 - 1 },
{ 2, -1 - 0 },
{ 0, -1 - 0 }
},
};
for (Polygon &p : poly) {
REQUIRE(p.area() > 0.);
for (Point &pt : p.points)
pt *= mm;
}
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
for (const OffsetTest &ot : {
OffsetTest { scale_(0.2), 2, 2 },
OffsetTest { scale_(0.4), 2, 2 },
OffsetTest { scale_(0.49), 2, 2 },
OffsetTest { scale_(0.5), 2, 2 },
OffsetTest { scale_(0.51), 2, 2 },
OffsetTest { scale_(0.56), 2, 2 },
OffsetTest { scale_(0.6), 2, 2 },
OffsetTest { scale_(0.7), 2, 2 },
OffsetTest { scale_(0.8), 1, 6 },
OffsetTest { scale_(0.9), 1, 6 },
OffsetTest { scale_(0.99), 1, 6 },
OffsetTest { scale_(1.0), 1, 0 },
OffsetTest { scale_(1.01), 1, 0 },
}) {
Polygons offsetted_polygons_out = Slic3r::Voronoi::offset(vd, lines, ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset3-out-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_out);
#endif
REQUIRE(offsetted_polygons_out.size() == ot.num_outer);
Polygons offsetted_polygons_in = Slic3r::Voronoi::offset(vd, lines, - ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset3-in-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_in);
#endif
REQUIRE(offsetted_polygons_in.size() == ot.num_inner);
}
}
TEST_CASE("Voronoi offset with edge collapse", "[VoronoiOffset4]")
{
Polygons poly
{
// Outer contour
{
{ 434890, -64754575 },
{ 541060, -64669076 },
{ 585647, -64583538 },
{ 576999, -64484233 },
{ 485666, -64191173 },
{ 1029323, -63646261 },
{ 1416925, -63666243 },
{ 1541532, -63643075 },
{ 1541535, -63643075 },
{ 1541535, -63643074 },
{ 1552612, -63641015 },
{ 1631609, -63568270 },
{ 1678393, -63443639 },
{ 1725519, -63219942 },
{ 1770552, -62903321 },
{ 1742544, -62755934 },
{ 1758152, -62588378 },
{ 1702289, -62474826 },
{ 1638627, -62242058 },
{ 1671281, -61938568 },
{ 1792676, -61478332 },
{ 1934894, -60760597 },
{ 2160333, -60064089 },
{ 2638183, -58972890 },
{ 2933095, -58478536 },
{ 3173586, -58159527 },
{ 3557779, -57556727 },
{ 3707088, -57158174 },
{ 3758053, -56907139 },
{ 3935932, -56278649 },
{ 4077331, -56033426 },
{ 4151386, -55768739 },
{ 4293796, -55561683 },
{ 4383089, -55387391 },
{ 4614128, -55201443 },
{ 5268755, -54333831 },
{ 5547634, -53797296 },
{ 5573864, -53639250 },
{ 5736812, -53304157 },
{ 6090973, -52066302 },
{ 6148630, -51666664 },
{ 6189511, -50974991 },
{ 6244112, -50774489 },
{ 6302489, -50761556 },
{ 6511179, -50579861 },
{ 6778128, -50398667 },
{ 6896879, -50350264 },
{ 7388259, -49913262 },
{ 7630584, -49602449 },
{ 7886846, -48987881 },
{ 7871333, -48318666 },
{ 7770349, -47841179 },
{ 7570223, -47234733 },
{ 7283115, -46705503 },
{ 6842948, -46056539 },
{ 6612732, -45760004 },
{ 6150430, -44991494 },
{ 5564326, -44168114 },
{ 5193032, -43807544 },
{ 4932097, -43489047 },
{ 3857385, -42548846 },
{ 3764745, -42081468 },
{ 3539887, -41422273 },
{ 3283048, -40803856 },
{ 3005925, -40367981 },
{ 3136185, -39834533 },
{ 3333757, -38499972 },
{ 3360660, -38183895 },
{ 3353375, -38036005 },
{ 3398808, -37582504 },
{ 3604229, -37221781 },
{ 3698079, -36962934 },
{ 4000449, -36007804 },
{ 4256811, -35016707 },
{ 4405951, -34581428 },
{ 4364534, -34178439 },
{ 4124603, -33432250 },
{ 3806159, -32765167 },
{ 3359088, -32109020 },
{ 2880790, -31317192 },
{ 1548334, -30402139 },
{ -7, -30131023 },
{ -1548347, -30402139 },
{ -2880803, -31317189 },
{ -3359100, -32109018 },
{ -3806173, -32765166 },
{ -4124617, -33432248 },
{ -4364548, -34178436 },
{ -4405966, -34581423 },
{ -4256825, -35016707 },
{ -4000461, -36007800 },
{ -3698093, -36962933 },
{ -3604243, -37221781 },
{ -3398823, -37582501 },
{ -3353390, -38036003 },
{ -3360675, -38183892 },
{ -3333772, -38499972 },
{ -3136200, -39834530 },
{ -3005940, -40367980 },
{ -3283062, -40803852 },
{ -3539902, -41422273 },
{ -3764761, -42081468 },
{ -3857402, -42548846 },
{ -4932112, -43489047 },
{ -5193047, -43807544 },
{ -5564341, -44168114 },
{ -6150446, -44991494 },
{ -6612748, -45760000 },
{ -6842965, -46056536 },
{ -7283130, -46705503 },
{ -7570238, -47234733 },
{ -7770365, -47841179 },
{ -7871349, -48318666 },
{ -7886860, -48987873 },
{ -7630599, -49602451 },
{ -7388277, -49913260 },
{ -6896896, -50350264 },
{ -6778145, -50398667 },
{ -6511196, -50579862 },
{ -6302504, -50761557 },
{ -6244127, -50774488 },
{ -6189527, -50974989 },
{ -6148648, -51666664 },
{ -6090990, -52066302 },
{ -5736829, -53304157 },
{ -5573882, -53639250 },
{ -5547651, -53797296 },
{ -5268772, -54333831 },
{ -4614145, -55201443 },
{ -4383106, -55387389 },
{ -4293814, -55561683 },
{ -4151404, -55768739 },
{ -4077350, -56033423 },
{ -3935952, -56278647 },
{ -3758072, -56907137 },
{ -3707107, -57158170 },
{ -3557796, -57556727 },
{ -3173605, -58159527 },
{ -2933113, -58478536 },
{ -2638201, -58972890 },
{ -2295003, -59738435 },
{ -2160353, -60064089 },
{ -1978487, -60596626 },
{ -1792695, -61478332 },
{ -1671298, -61938574 },
{ -1638646, -62242058 },
{ -1702306, -62474826 },
{ -1758168, -62588380 },
{ -1742563, -62755934 },
{ -1770570, -62903317 },
{ -1725537, -63219946 },
{ -1678412, -63443639 },
{ -1631627, -63568270 },
{ -1553479, -63640201 },
{ -1416944, -63666243 },
{ -998854, -63645714 },
{ -485685, -64191173 },
{ -577019, -64484225 },
{ -585667, -64583538 },
{ -541079, -64669076 },
{ -434910, -64754575 },
{ -294192, -64810609 },
{ 294172, -64810609 },
},
// Hole 1
{
{ -842246, -45167428 },
{ -1473641, -45154392 },
{ -2181728, -45100161 },
{ -2804308, -44985842 },
{ -3100514, -44879269 },
{ -3836807, -44802155 },
{ -4035816, -44718913 },
{ -4167175, -44583299 },
{ -4496705, -44467674 },
{ -4486674, -44382045 },
{ -4343949, -44070577 },
{ -3740991, -43494686 },
{ -2701372, -43313358 },
{ -1493599, -43312838 },
{ -8, -43352868 },
{ 1414575, -43313336 },
{ 2701358, -43313358 },
{ 3095462, -43374735 },
{ 3740975, -43494686 },
{ 4343934, -44070583 },
{ 4486657, -44382044 },
{ 4496688, -44467670 },
{ 4167159, -44583300 },
{ 4035800, -44718913 },
{ 3836792, -44802155 },
{ 3100498, -44879269 },
{ 2804292, -44985842 },
{ 2181712, -45100161 },
{ 1473625, -45154389 },
{ 842231, -45167428 },
{ -8, -45232686 },
},
// Hole 2
{
{ 1657455, -63016679 },
{ 1723196, -63056286 },
{ 1541535, -63643074 },
{ 1541532, -63643075 },
{ 1030020, -63645562 },
}
};
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
for (const OffsetTest &ot : {
OffsetTest { scale_(0.2), 2, 2 },
OffsetTest { scale_(0.4), 2, 2 },
OffsetTest { scale_(0.49), 2, 3 },
OffsetTest { scale_(0.51), 2, 2 },
OffsetTest { scale_(0.56), 2, 2 },
OffsetTest { scale_(0.6), 2, 2 },
OffsetTest { scale_(0.7), 2, 2 },
OffsetTest { scale_(0.8), 2, 2 },
OffsetTest { scale_(0.9), 2, 2 },
OffsetTest { scale_(0.99), 1, 2 },
OffsetTest { scale_(1.0), 1, 2 },
OffsetTest { scale_(1.01), 1, 2 },
}) {
Polygons offsetted_polygons_out = Slic3r::Voronoi::offset(vd, lines, ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset3-out-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_out);
#endif
REQUIRE(offsetted_polygons_out.size() == ot.num_outer);
Polygons offsetted_polygons_in = Slic3r::Voronoi::offset(vd, lines, - ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset3-in-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_in);
#endif
REQUIRE(offsetted_polygons_in.size() == ot.num_inner);
}
}
// A sample extracted from file medallion_printable_fixed-teeth.stl from https://www.thingiverse.com/thing:1347129
// This test for offset scale_(2.9) and bigger
// triggers assert(r < std::max(d0, d1) + EPSILON) in function first_circle_segment_intersection_parameter.
TEST_CASE("Voronoi offset 5", "[VoronoiOffset5]")
{
Polygons poly = {
Polygon {
{ 0 , -16077501 },
{ 3015222 , -16142836 },
{ 3072642 , -16138163 },
{ 3094279 , -16105662 },
{ 3110660 , -15140728 },
{ 3157438 , -14105326 },
{ 3338367 , -11081394 },
{ 3443412 , -8381621 },
{ 3472489 , -6084497 },
{ 3445790 , -5962924 },
{ 3061725 , -6003484 },
{ 3030326 , -6030622 },
{ 2989343 , -6270378 },
{ 2903752 , -7368176 },
{ 2856704 , -7740619 },
{ 2795743 , -7978809 },
{ 2729231 , -8098866 },
{ 2666509 , -8131138 },
{ 2614169 , -8112308 },
{ 2561157 , -8032014 },
{ 2488290 , -7479351 },
{ 2453360 , -6911556 },
{ 2456148 , -6463146 },
{ 2546029 , -4580396 },
{ 2688181 , -2593262 },
{ 2717617 , -1700519 },
{ 2682232 , -1128411 },
{ 2631029 , -832886 },
{ 2535941 , -504483 },
{ 2399115 , -199303 },
{ 2290997 , -171213 },
{ 611824 , -132865 },
{ 6419 , -375849 },
{ -611825 , -132865 },
{ -2377355 , -185241 },
{ -2420740 , -231171 },
{ -2535942 , -504484 },
{ -2631030 , -832887 },
{ -2684831 , -1150821 },
{ -2714840 , -1586454 },
{ -2688181 , -2593262 },
{ -2546030 , -4580396 },
{ -2456149 , -6463145 },
{ -2453361 , -6911557 },
{ -2488291 , -7479352 },
{ -2561159 , -8032018 },
{ -2614171 , -8112309 },
{ -2666509 , -8131138 },
{ -2729233 , -8098868 },
{ -2795744 , -7978809 },
{ -2856706 , -7740619 },
{ -2903752 , -7368176 },
{ -2989345 , -6270378 },
{ -3030327 , -6030622 },
{ -3061726 , -6003484 },
{ -3445790 , -5962924 },
{ -3472490 , -6084498 },
{ -3468804 , -7244095 },
{ -3399287 , -9714025 },
{ -3338368 , -11081395 },
{ -3141015 , -14446051 },
{ -3094280 , -16105662 },
{ -3072643 , -16138163 },
{ -3008836 , -16143225 }
}
};
double area = std::accumulate(poly.begin(), poly.end(), 0., [](double a, auto &poly){ return a + poly.area(); });
REQUIRE(area > 0.);
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
for (const OffsetTest &ot : {
OffsetTest { scale_(2.8), 1, 1 },
OffsetTest { scale_(2.9), 1, 1 },
OffsetTest { scale_(3.0), 1, 1 },
}) {
Polygons offsetted_polygons_out = Slic3r::Voronoi::offset(vd, lines, ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset5-out-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_out);
#endif
REQUIRE(offsetted_polygons_out.size() == ot.num_outer);
Polygons offsetted_polygons_in = Slic3r::Voronoi::offset(vd, lines, - ot.distance, scale_(0.005));
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-offset5-in-%lf.svg", ot.distance).c_str(),
vd, Points(), lines, offsetted_polygons_in);
#endif
REQUIRE(offsetted_polygons_in.size() == ot.num_inner);
}
}
TEST_CASE("Voronoi skeleton", "[VoronoiSkeleton]")
{
coord_t mm = coord_t(scale_(1.));
Polygons poly = {
Polygon {
{ 0, 0 },
{ 1, 0 },
{ 1, 1 },
{ 2, 1 },
{ 2, 0 },
{ 3, 0 },
{ 3, 2 },
{ 0, 2 }
},
Polygon {
{ 0, - 1 - 2 },
{ 3, - 1 - 2 },
{ 3, - 1 - 0 },
{ 2, - 1 - 0 },
{ 2, - 1 - 1 },
{ 1, - 1 - 1 },
{ 1, - 1 - 0 },
{ 0, - 1 - 0 }
},
};
for (Polygon &p : poly)
for (Point &pt : p.points)
pt *= mm;
double area = std::accumulate(poly.begin(), poly.end(), 0., [](double a, auto &poly){ return a + poly.area(); });
REQUIRE(area > 0.);
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
Slic3r::Voronoi::annotate_inside_outside(vd, lines);
Slic3r::Voronoi::annotate_inside_outside(vd, lines);
static constexpr double threshold_alpha = M_PI / 12.; // 30 degrees
std::vector<Vec2d> skeleton_edges = Slic3r::Voronoi::skeleton_edges_rough(vd, lines, threshold_alpha);
REQUIRE(! skeleton_edges.empty());
}
// Simple detection with complexity N^2 if there is any point in the input polygons that doesn't have Voronoi vertex.
[[maybe_unused]] static bool has_missing_voronoi_vertices(const Polygons &polygons, const VD &vd)
{
auto are_equal = [](const VD::vertex_type v, const Point &p) { return (Vec2d(v.x(), v.y()) - p.cast<double>()).norm() <= SCALED_EPSILON; };
Points poly_points = to_points(polygons);
std::vector<bool> found_vertices(poly_points.size());
for (const Point &point : poly_points)
for (const auto &vertex : vd.vertices())
if (are_equal(vertex, point)) {
found_vertices[&point - &poly_points.front()] = true;
break;
}
return std::find(found_vertices.begin(), found_vertices.end(), false) != found_vertices.end();
}
// This case is composed of one square polygon, and one of the edges is divided into two parts by a point that lies on this edge.
// In some applications, this point is unnecessary and can be removed (merge two parts to one edge). But for the case of
// multi-material segmentation, these points are necessary. In this case, Voronoi vertex for the point, which divides the edge
// into two parts. Even we add more points to the edge, and then for these points, the Voronoin vertex is also missing. An
// infinity-edge passes through the missing Voronoi vertex. Therefore, this missing Voronoi vertex and edge can be reconstructed
// using the intersection between the infinity-edge with the input polygon.
// Rotation of the polygon solves this problem.
TEST_CASE("Voronoi missing vertex 1", "[VoronoiMissingVertex1]")
{
Polygon poly = {
{ 25000000, 25000000},
{-25000000, 25000000},
{-25000000, -25000000},
{-12412500, -25000000},
// {- 1650000, -25000000},
{ 25000000, -25000000}
};
// poly.rotate(PI / 6);
REQUIRE(poly.area() > 0.);
REQUIRE(intersecting_edges({poly}).empty());
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex1-out.svg").c_str(), vd, Points(), lines);
#endif
// REQUIRE(!has_missing_voronoi_vertices({poly}, vd));
}
// This case is composed of two square polygons (contour and hole), and again one of the edges is divided into two parts by a
// point that lies on this edge, and for this point is Voronoi vertex missing. A difference between the previous and this case is
// that for this case, through the missing Voronoi vertex is passing a finite edge between two internal Voronoin vertices.
// Therefore, this missing Voronoi vertex and edge can be reconstructed using the intersection between the finite edge with the
// input polygon.
// Rotation of the polygons solves this problem.
TEST_CASE("Voronoi missing vertex 2", "[VoronoiMissingVertex2]")
{
Polygons poly = {
Polygon {
{ 50000000, 50000000},
{-50000000, 50000000},
{-50000000, -50000000},
{ 50000000, -50000000},
},
Polygon {
{-45000000, -45000000},
{-45000000, 45000000},
{ 45000000, 45000000},
{ 45000000, 8280000},
{ 45000000, -45000000},
}
};
// polygons_rotate(poly, PI / 6);
double area = std::accumulate(poly.begin(), poly.end(), 0., [](double a, auto &poly) { return a + poly.area(); });
REQUIRE(area > 0.);
REQUIRE(intersecting_edges(poly).empty());
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex2-out.svg").c_str(), vd, Points(), lines);
#endif
// REQUIRE(!has_missing_voronoi_vertices(poly, vd));
}
// This case is composed of two polygons, and again one of the edges is divided into two parts by a point that lies on this edge,
// and for this point is Voronoi vertex missing. A difference between the previous cases and this case through the missing
// Voronoi vertex is passing finite edge between one inner Voronoi vertex and one outer Voronoi vertex.
// Rotating the polygon also help solve this problem.
TEST_CASE("Voronoi missing vertex 3", "[VoronoiMissingVertex3]")
{
Polygons poly = {
Polygon {
{-29715088, -29310899},
{-29022573, -28618384},
{-27771147, -27366958},
{-28539221, -26519393},
{-30619013, -28586348},
{-29812018, -29407830},
},
Polygon {
{-27035112, -28071875},
{-27367482, -27770679},
{-28387008, -28790205},
{-29309438, -29712635},
{-29406319, -29809515},
{-29032985, -30179156},
}
};
double area = std::accumulate(poly.begin(), poly.end(), 0., [](double a, auto &poly){ return a + poly.area(); });
REQUIRE(area > 0.);
REQUIRE(intersecting_edges(poly).empty());
// polygons_rotate(poly, PI/180);
// polygons_rotate(poly, PI/6);
BoostVD vd;
Lines lines = to_lines(poly);
construct_voronoi(lines.begin(), lines.end(), &vd);
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-missing-vertex3-out.svg").c_str(), vd, Points(), lines);
#endif
// REQUIRE(!has_missing_voronoi_vertices(poly, vd));
}
// In this case, the Voronoi vertex (146873, -146873) is included twice.
// Also, near to those duplicate Voronoi vertices is another Voronoi vertex (146872, -146872).
// Rotating the polygon will help solve this problem, but then there arise three very close Voronoi vertices.
// Rotating of the input polygon will help solve this problem.
TEST_CASE("Duplicate Voronoi vertices", "[Voronoi]")
{
Polygon poly = {
{ 25000000, 25000000},
{-25000000, 25000000},
{-25000000, -25000000},
{ 146872, -25000000},
{ 9912498, -25000000},
{ 25000000, -25000000},
{ 25000000, - 8056252},
{ 25000000, - 146873},
{ 25000000, 10790627},
};
// poly.rotate(PI / 6);
REQUIRE(poly.area() > 0.);
REQUIRE(intersecting_edges({poly}).empty());
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-duplicate-vertices-out.svg").c_str(), vd, Points(), lines);
#endif
[[maybe_unused]] auto has_duplicate_vertices = [](const VD &vd) -> bool {
std::vector<Vec2d> vertices;
for (const auto &vertex : vd.vertices())
vertices.emplace_back(Vec2d(vertex.x(), vertex.y()));
std::sort(vertices.begin(), vertices.end(), [](const Vec2d &l, const Vec2d &r) { return l.x() < r.x() || (l.x() == r.x() && l.y() < r.y()); });
return std::unique(vertices.begin(), vertices.end()) != vertices.end();
};
// REQUIRE(!has_duplicate_vertices(vd));
}
// In this case, there are three very close Voronoi vertices like in the previous test case after rotation. There is also one
// missing Voronoi vertex. One infinity-edge (after clip [(146872, -70146871), (146872, -146871)]) passes through this missing
// Voronoi vertex. This infinite edge [(146872, -70146871), (146872, -146871)] and edge [(146873, -146873), (0, 0)] are intersecting.
// They intersect probably because the three points are very close to each other, with a combination of the missing Voronoi vertex.
// Rotating of the input polygon will help solve this problem.
TEST_CASE("Intersecting Voronoi edges", "[Voronoi]")
{
Polygon poly = {
{ 25000000, 25000000},
{-25000000, 25000000},
{-25000000, -25000000},
{ 146872, -25000000},
{ 25000000, -25000000},
{ 25000000, - 146873},
};
// poly.rotate(PI / 6);
REQUIRE(poly.area() > 0.);
REQUIRE(intersecting_edges({poly}).empty());
VD vd;
Lines lines = to_lines(poly);
vd.construct_voronoi(lines.begin(), lines.end());
#ifdef VORONOI_DEBUG_OUT
dump_voronoi_to_svg(debug_out_path("voronoi-intersecting-edges-out.svg").c_str(), vd, Points(), lines);
#endif
[[maybe_unused]] auto has_intersecting_edges = [](const Polygon &poly, const VD &vd) -> bool {
BoundingBox bbox = get_extents(poly);
const double bbox_dim_max = double(std::max(bbox.size().x(), bbox.size().y()));
std::vector<Voronoi::Internal::segment_type> segments;
for (const Line &line : to_lines(poly))
segments.emplace_back(Voronoi::Internal::point_type(double(line.a.x()), double(line.a.y())),
Voronoi::Internal::point_type(double(line.b.x()), double(line.b.y())));
Lines edges;
for (const auto &edge : vd.edges())
if (edge.cell()->source_index() < edge.twin()->cell()->source_index()) {
if (edge.is_finite()) {
edges.emplace_back(Point(coord_t(edge.vertex0()->x()), coord_t(edge.vertex0()->y())),
Point(coord_t(edge.vertex1()->x()), coord_t(edge.vertex1()->y())));
} else if (edge.is_infinite()) {
std::vector<Voronoi::Internal::point_type> samples;
Voronoi::Internal::clip_infinite_edge(poly.points, segments, edge, bbox_dim_max, &samples);
if (!samples.empty())
edges.emplace_back(Point(coord_t(samples[0].x()), coord_t(samples[0].y())), Point(coord_t(samples[1].x()), coord_t(samples[1].y())));
}
}
Point intersect_point;
for (auto first_it = edges.begin(); first_it != edges.end(); ++first_it)
for (auto second_it = first_it + 1; second_it != edges.end(); ++second_it)
if (first_it->intersection(*second_it, &intersect_point) && first_it->a != intersect_point && first_it->b != intersect_point)
return true;
return false;
};
// REQUIRE(!has_intersecting_edges(poly, vd));
}