/* KLayout Layout Viewer Copyright (C) 2006-2017 Matthias Koefferlein This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "dbPolygon.h" #include "dbPolygonTools.h" #include "dbEdgeProcessor.h" #include "dbPolygonGenerators.h" #include "utHead.h" TEST(1) { db::Box box (0, 0, 1000, 1000); db::Polygon in (box); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (0, 500), db::Point (1, 500)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,500;1000,500;1000,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, -100), db::Point (1, -100)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 0); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 0), db::Point (1, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 0); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 1000), db::Point (1, 1000)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,1000;1000,1000;1000,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 1001), db::Point (1, 1001)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,1000;1000,1000;1000,0)"); } TEST(2) { std::vector c; c.push_back (db::Point (0, 0)); c.push_back (db::Point (0, 400)); c.push_back (db::Point (400, 400)); c.push_back (db::Point (400, 100)); c.push_back (db::Point (600, 100)); c.push_back (db::Point (600, 300)); c.push_back (db::Point (700, 300)); c.push_back (db::Point (700, 0)); c.push_back (db::Point (300, 0)); c.push_back (db::Point (300, 300)); c.push_back (db::Point (100, 300)); c.push_back (db::Point (100, 100)); c.push_back (db::Point (200, 100)); c.push_back (db::Point (200, 0)); db::Polygon in; in.assign_hull (c.begin (), c.end ()); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (0, 200), db::Point (1, 200)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,200;100,200;100,100;200,100;200,0)"); EXPECT_EQ (right_of[1].to_string (), "(300,0;300,200;400,200;400,100;600,100;600,200;700,200;700,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 100), db::Point (1, 100)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,100;200,100;200,0)"); EXPECT_EQ (right_of[1].to_string (), "(300,0;300,100;700,100;700,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 50), db::Point (1, 50)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,50;200,50;200,0)"); EXPECT_EQ (right_of[1].to_string (), "(300,0;300,50;700,50;700,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 300), db::Point (1, 300)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,300;100,300;100,100;200,100;200,0)"); EXPECT_EQ (right_of[1].to_string (), "(300,0;300,300;400,300;400,100;600,100;600,300;700,300;700,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 400), db::Point (1, 400)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,400;400,400;400,100;600,100;600,300;700,300;700,0;300,0;300,300;100,300;100,100;200,100;200,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 500), db::Point (1, 500)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,400;400,400;400,100;600,100;600,300;700,300;700,0;300,0;300,300;100,300;100,100;200,100;200,0)"); } TEST(3) { db::Box box (0, 0, 1000, 1000); db::Polygon in (box); std::vector c; c.push_back (db::Point (100, 100)); c.push_back (db::Point (100, 400)); c.push_back (db::Point (200, 400)); c.push_back (db::Point (200, 100)); in.insert_hole (c.begin (), c.end ()); c.clear (); c.push_back (db::Point (400, 100)); c.push_back (db::Point (400, 400)); c.push_back (db::Point (500, 400)); c.push_back (db::Point (500, 100)); in.insert_hole (c.begin (), c.end ()); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (0, 200), db::Point (1, 200)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,200;100,200;100,100;200,100;200,200;400,200;400,100;500,100;500,200;1000,200;1000,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 50), db::Point (1, 50)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,50;1000,50;1000,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 500), db::Point (1, 500)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,500;1000,500;1000,0/100,100;200,100;200,400;100,400/400,100;500,100;500,400;400,400)"); } TEST(4) { std::vector c; c.push_back (db::Point (0, 0)); c.push_back (db::Point (0, 400)); c.push_back (db::Point (400, 400)); c.push_back (db::Point (400, 200)); c.push_back (db::Point (300, 200)); c.push_back (db::Point (300, 100)); c.push_back (db::Point (400, 100)); c.push_back (db::Point (400, 400)); c.push_back (db::Point (600, 400)); c.push_back (db::Point (600, 0)); db::Polygon in; in.assign_hull (c.begin (), c.end ()); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (0, 300), db::Point (1, 300)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,300;400,300;400,200;300,200;300,100;400,100;400,300;600,300;600,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (1, 300), db::Point (0, 300)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(400,300;400,400;600,400;600,300)"); EXPECT_EQ (right_of[1].to_string (), "(0,300;0,400;400,400;400,300)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 50), db::Point (1, 50)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,50;600,50;600,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 100), db::Point (1, 100)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,100;600,100;600,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 150), db::Point (1, 150)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,150;300,150;300,100;400,100;400,150;600,150;600,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (0, 200), db::Point (1, 200)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,200;300,200;300,100;400,100;400,200;600,200;600,0)"); } TEST(5) { std::vector c; c.push_back (db::Point (0, 0)); c.push_back (db::Point (0, 884)); c.push_back (db::Point (1010, 884)); c.push_back (db::Point (1010, 396)); c.push_back (db::Point (565, 396)); c.push_back (db::Point (565, 372)); c.push_back (db::Point (568, 372)); c.push_back (db::Point (568, 396)); c.push_back (db::Point (1010, 396)); c.push_back (db::Point (1010, 332)); c.push_back (db::Point (72, 332)); c.push_back (db::Point (72, 313)); c.push_back (db::Point (89, 313)); c.push_back (db::Point (89, 332)); c.push_back (db::Point (1010, 332)); c.push_back (db::Point (1010, 327)); c.push_back (db::Point (173, 327)); c.push_back (db::Point (173, 304)); c.push_back (db::Point (211, 304)); c.push_back (db::Point (211, 327)); c.push_back (db::Point (1010, 327)); c.push_back (db::Point (1010, 302)); c.push_back (db::Point (174, 302)); c.push_back (db::Point (174, 275)); c.push_back (db::Point (212, 275)); c.push_back (db::Point (212, 302)); c.push_back (db::Point (1010, 302)); c.push_back (db::Point (1010, 268)); c.push_back (db::Point (47, 268)); c.push_back (db::Point (47, 257)); c.push_back (db::Point (62, 257)); c.push_back (db::Point (62, 268)); c.push_back (db::Point (1010, 268)); c.push_back (db::Point (1010, 243)); c.push_back (db::Point (49, 243)); c.push_back (db::Point (49, 231)); c.push_back (db::Point (63, 231)); c.push_back (db::Point (63, 243)); c.push_back (db::Point (1010, 243)); c.push_back (db::Point (1010, 214)); c.push_back (db::Point (72, 214)); c.push_back (db::Point (72, 194)); c.push_back (db::Point (93, 194)); c.push_back (db::Point (93, 214)); c.push_back (db::Point (1010, 214)); c.push_back (db::Point (1010, 77)); c.push_back (db::Point (5, 77)); c.push_back (db::Point (5, 15)); c.push_back (db::Point (67, 15)); c.push_back (db::Point (67, 77)); c.push_back (db::Point (1010, 77)); c.push_back (db::Point (1010, 38)); c.push_back (db::Point (328, 38)); c.push_back (db::Point (328, 17)); c.push_back (db::Point (405, 17)); c.push_back (db::Point (405, 38)); c.push_back (db::Point (1010, 38)); c.push_back (db::Point (1010, 0)); db::Polygon in; in.assign_hull (c.begin (), c.end ()); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (565, 1), db::Point (565, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,884;565,884;565,332;72,332;72,313;89,313;89,332;565,332;565,327;173,327;173,304;211,304;211,327;565,327;565,302;174,302;174,275;212,275;212,302;565,302;565,268;47,268;47,257;62,257;62,268;565,268;565,243;49,243;49,231;63,231;63,243;565,243;565,214;72,214;72,194;93,194;93,214;565,214;565,77;5,77;5,15;67,15;67,77;565,77;565,38;328,38;328,17;405,17;405,38;565,38;565,0)"); } TEST(6) { std::vector c; c.push_back (db::Point (0, 0)); c.push_back (db::Point (0, 100)); c.push_back (db::Point (100, 100)); c.push_back (db::Point (200, 200)); c.push_back (db::Point (300, 100)); c.push_back (db::Point (400, 100)); c.push_back (db::Point (400, 400)); c.push_back (db::Point (500, 400)); c.push_back (db::Point (500, 0)); db::Polygon in; in.assign_hull (c.begin (), c.end ()); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (0, 200), db::Point (1, 200)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,100;100,100;200,200;300,100;400,100;400,200;500,200;500,0)"); c.push_back (db::Point ()); } TEST(7) { std::vector c; c.push_back (db::Point (0, 0)); c.push_back (db::Point (0, 1)); c.push_back (db::Point (3, 1)); c.push_back (db::Point (3, 0)); c.push_back (db::Point (0, 1)); c.push_back (db::Point (2, 0)); db::Polygon in; in.assign_hull (c.begin (), c.end ()); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (2, 0), db::Point (2, 1)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(2,0;2,1;3,1;3,0)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (2, 1), db::Point (2, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,1;2,1;2,0)"); } TEST(8) { std::vector c; c.push_back (db::Point (0, 0)); c.push_back (db::Point (0, 300)); c.push_back (db::Point (300, 300)); c.push_back (db::Point (200, 200)); c.push_back (db::Point (100, 200)); c.push_back (db::Point (100, 100)); c.push_back (db::Point (200, 200)); c.push_back (db::Point (150, 50)); c.push_back (db::Point (300, 50)); c.push_back (db::Point (300, 0)); db::Polygon in; in.assign_hull (c.begin (), c.end ()); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (200, 0), db::Point (200, 1)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(200,0;200,50;300,50;300,0)"); EXPECT_EQ (right_of[1].to_string (), "(200,200;200,300;300,300)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (200, 1), db::Point (200, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(0,0;0,300;200,300;200,200;100,200;100,100;200,200;150,50;200,50;200,0)"); } TEST(9) { std::vector c; c.push_back (db::Point (0, 0)); c.push_back (db::Point (0, 200)); c.push_back (db::Point (250, 200)); c.push_back (db::Point (250, 100)); c.push_back (db::Point (300, 100)); c.push_back (db::Point (300, 200)); c.push_back (db::Point (0, 200)); c.push_back (db::Point (0, 500)); c.push_back (db::Point (400, 500)); c.push_back (db::Point (400, 400)); c.push_back (db::Point (100, 400)); c.push_back (db::Point (100, 300)); c.push_back (db::Point (150, 300)); c.push_back (db::Point (150, 400)); c.push_back (db::Point (400, 400)); c.push_back (db::Point (400, 0)); db::Polygon in; in.assign_hull (c.begin (), c.end ()); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (200, 0), db::Point (200, 1)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(200,0;200,200;250,200;250,100;300,100;300,200;200,200;200,400;400,400;400,0)"); EXPECT_EQ (right_of[1].to_string (), "(200,400;200,500;400,500;400,400)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (200, 1), db::Point (200, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(0,200;0,500;200,500;200,400;100,400;100,300;150,300;150,400;200,400;200,200)"); EXPECT_EQ (right_of[1].to_string (), "(0,0;0,200;200,200;200,0)"); } TEST(9a) { std::vector c; c.push_back (db::Point (942, 10230)); c.push_back (db::Point (943, 10272)); c.push_back (db::Point (988, 10278)); c.push_back (db::Point (999, 10278)); c.push_back (db::Point (1002, 10280)); c.push_back (db::Point (1034, 10280)); c.push_back (db::Point (1032, 10285)); c.push_back (db::Point (1090, 10285)); c.push_back (db::Point (1090, 10302)); c.push_back (db::Point (1043, 10302)); c.push_back (db::Point (1041, 10286)); c.push_back (db::Point (1036, 10285)); c.push_back (db::Point (1031, 10297)); c.push_back (db::Point (1027, 10297)); c.push_back (db::Point (1032, 10285)); c.push_back (db::Point (1022, 10283)); c.push_back (db::Point (1024, 10288)); c.push_back (db::Point (1011, 10288)); c.push_back (db::Point (1017, 10283)); c.push_back (db::Point (1003, 10281)); c.push_back (db::Point (1011, 10288)); c.push_back (db::Point (1024, 10288)); c.push_back (db::Point (1027, 10297)); c.push_back (db::Point (1031, 10297)); c.push_back (db::Point (1029, 10302)); c.push_back (db::Point (1027, 10297)); c.push_back (db::Point (1026, 10300)); c.push_back (db::Point (1028, 10302)); c.push_back (db::Point (994, 10302)); c.push_back (db::Point (1002, 10280)); c.push_back (db::Point (988, 10278)); c.push_back (db::Point (983, 10281)); c.push_back (db::Point (942, 10281)); c.push_back (db::Point (942, 10230)); c.push_back (db::Point (1019, 10230)); c.push_back (db::Point (1017, 10237)); c.push_back (db::Point (1027, 10252)); c.push_back (db::Point (1090, 10252)); c.push_back (db::Point (1090, 10285)); c.push_back (db::Point (1036, 10285)); c.push_back (db::Point (1039, 10277)); c.push_back (db::Point (1038, 10269)); c.push_back (db::Point (1034, 10280)); c.push_back (db::Point (1021, 10280)); c.push_back (db::Point (1037, 10266)); c.push_back (db::Point (1027, 10252)); c.push_back (db::Point (1014, 10260)); c.push_back (db::Point (1016, 10265)); c.push_back (db::Point (1007, 10265)); c.push_back (db::Point (1014, 10260)); c.push_back (db::Point (1012, 10252)); c.push_back (db::Point (1007, 10265)); c.push_back (db::Point (1016, 10265)); c.push_back (db::Point (1021, 10280)); c.push_back (db::Point (1002, 10280)); c.push_back (db::Point (1007, 10265)); c.push_back (db::Point (994, 10274)); c.push_back (db::Point (999, 10278)); c.push_back (db::Point (988, 10278)); c.push_back (db::Point (994, 10274)); db::Polygon in; db::Polygon::contour_type contour; contour.assign (c.begin (), c.end (), false, false, true); in.assign_hull (contour); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (1016, 0), db::Point (1016, 1)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 4); EXPECT_EQ (right_of[0].to_string (), "(1016,10230;1016,10259;1027,10252;1037,10266;1021,10280;1034,10280;1038,10269;1039,10277;1036,10285;1090,10285;1090,10252;1027,10252;1017,10237;1019,10230)"); EXPECT_EQ (right_of[1].to_string (), "(1016,10265;1016,10280;1021,10280)"); EXPECT_EQ (right_of[2].to_string (), "(1016,10280;1016,10283;1017,10283;1016,10284;1016,10288;1024,10288;1022,10283;1032,10285;1027,10297;1031,10297;1036,10285;1041,10286;1043,10302;1090,10302;1090,10285;1032,10285;1034,10280)"); EXPECT_EQ (right_of[3].to_string (), "(1016,10288;1016,10302;1028,10302;1026,10300;1027,10297;1029,10302;1031,10297;1027,10297;1024,10288)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (1016, 1), db::Point (1016, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(942,10230;994,10274;988,10278;999,10278;994,10274;1007,10265;1002,10280;1016,10280;1016,10265;1007,10265;1012,10252;1014,10260;1007,10265;1016,10265;1014,10260;1016,10259;1016,10230;942,10230;942,10281;983,10281;988,10278;1002,10280;994,10302;1016,10302;1016,10288;1011,10288;1003,10281;1016,10283;1016,10280;1002,10280;999,10278;988,10278;943,10272)"); EXPECT_EQ (right_of[1].to_string (), "(1016,10284;1011,10288;1016,10288)"); } TEST(9b) { std::vector c; c.push_back (db::Point (942, 10230)); c.push_back (db::Point (942, 10265)); c.push_back (db::Point (943, 10265)); c.push_back (db::Point (942, 10230)); c.push_back (db::Point (983, 10265)); c.push_back (db::Point (1007, 10265)); c.push_back (db::Point (1012, 10252)); c.push_back (db::Point (1014, 10260)); c.push_back (db::Point (1007, 10265)); c.push_back (db::Point (1016, 10265)); c.push_back (db::Point (1014, 10260)); c.push_back (db::Point (1016, 10259)); c.push_back (db::Point (1016, 10230)); db::Polygon in; db::Polygon::contour_type contour; contour.assign (c.begin (), c.end (), false, false, true); in.assign_hull (contour); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (1007, 0), db::Point (1007, 1)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(1007,10230;1007,10265;1012,10252;1014,10260;1007,10265;1016,10265;1014,10260;1016,10259;1016,10230)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (1007, 1), db::Point (1007, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(942,10230;942,10265;943,10265;942,10230;983,10265;1007,10265;1007,10230)"); } TEST(9c) { std::vector c; c.push_back (db::Point (14335, 8265)); c.push_back (db::Point (14335, 10265)); c.push_back (db::Point (17335, 10265)); c.push_back (db::Point (15335, 10265)); c.push_back (db::Point (15335, 9765)); c.push_back (db::Point (15668, 9932)); c.push_back (db::Point (15335, 10265)); c.push_back (db::Point (17335, 10265)); c.push_back (db::Point (17335, 10015)); c.push_back (db::Point (15835, 10015)); c.push_back (db::Point (15668, 9932)); c.push_back (db::Point (15835, 9765)); c.push_back (db::Point (16002, 9932)); c.push_back (db::Point (15835, 10015)); c.push_back (db::Point (17335, 10015)); c.push_back (db::Point (17335, 9765)); c.push_back (db::Point (15335, 9765)); c.push_back (db::Point (14335, 9265)); c.push_back (db::Point (15335, 9265)); c.push_back (db::Point (15335, 9765)); c.push_back (db::Point (17335, 9765)); c.push_back (db::Point (17335, 8265)); c.push_back (db::Point (16335, 9265)); c.push_back (db::Point (15335, 9265)); db::Polygon in; db::Polygon::contour_type contour; contour.assign (c.begin (), c.end (), false, false, true); in.assign_hull (contour); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (15835, 0), db::Point (15835, 1)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 3); EXPECT_EQ (right_of[0].to_string (), "(17335,8265;16335,9265;15835,9265;15835,9765;17335,9765)"); EXPECT_EQ (right_of[1].to_string (), "(15835,9765;16002,9932;15835,10015;17335,10015;17335,9765)"); EXPECT_EQ (right_of[2].to_string (), "(15835,10015;15835,10265;17335,10265;17335,10015)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (15835, 1), db::Point (15835, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(14335,8265;14335,10265;15335,10265;15335,9765;15668,9932;15335,10265;15835,10265;15835,10015;15668,9932;15835,9765;15335,9765;14335,9265;15335,9265;15335,9765;15835,9765;15835,9265;15335,9265)"); } TEST(9d) { std::vector c; c.push_back (db::Point (17335, 8265)); c.push_back (db::Point (16335, 9265)); c.push_back (db::Point (15335, 9265)); c.push_back (db::Point (15335, 9765)); c.push_back (db::Point (15668, 9932)); c.push_back (db::Point (15835, 9765)); c.push_back (db::Point (16002, 9932)); c.push_back (db::Point (15835, 10015)); c.push_back (db::Point (15668, 9932)); c.push_back (db::Point (15335, 10265)); c.push_back (db::Point (17335, 10265)); db::Polygon in; db::Polygon::contour_type contour; contour.assign (c.begin (), c.end (), false, false, true); in.assign_hull (contour); std::vector right_of; db::cut_polygon (in, db::Edge (db::Point (16002, 0), db::Point (16002, 1)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 1); EXPECT_EQ (right_of[0].to_string (), "(17335,8265;16335,9265;16002,9265;16002,10265;17335,10265)"); right_of.clear (); db::cut_polygon (in, db::Edge (db::Point (16002, 1), db::Point (16002, 0)), std::back_inserter (right_of)); EXPECT_EQ (right_of.size (), 2); EXPECT_EQ (right_of[0].to_string (), "(15668,9932;15335,10265;16002,10265;16002,9932;15835,10015)"); EXPECT_EQ (right_of[1].to_string (), "(15335,9265;15335,9765;15668,9932;15835,9765;16002,9932;16002,9265)"); } TEST(10) { // Simple test for polygon-box interaction (integer coordinates) db::Polygon poly; db::Point p[] = { db::Point (0, 100), db::Point (100, 100), db::Point (0, 0) }; poly.assign_hull (p, p + sizeof (p) / sizeof (p[0])); EXPECT_EQ (interact (db::Box (0, 0, 100, 100), db::Box (-10, 100, 5, 110)), true); EXPECT_EQ (interact (db::Box (0, 0, 100, 100), db::Box (-10, -10, 110, 110)), true); EXPECT_EQ (interact (db::Box (0, 0, 100, 100), db::Box (-10, -10, 50, 110)), true); EXPECT_EQ (interact (db::Box (0, 0, 100, 100), db::Box ()), false); EXPECT_EQ (interact (poly, db::Box (-10, -10, -1, -1)), false); EXPECT_EQ (interact (poly, db::Box (-10, -10, 0, 0)), true); EXPECT_EQ (interact (poly, db::Box (-10, -10, 1, 1)), true); EXPECT_EQ (interact (poly, db::Box (-10, -10, 20, 10)), true); EXPECT_EQ (interact (poly, db::Box (10, 20, 20, 30)), true); EXPECT_EQ (interact (poly, db::Box (10, 20, 15, 25)), true); EXPECT_EQ (interact (poly, db::Box (30, 10, 40, 20)), false); EXPECT_EQ (interact (poly, db::Box (30, 20, 40, 30)), true); EXPECT_EQ (interact (poly, db::Box (-10, 20, 0, 30)), true); EXPECT_EQ (interact (poly, db::Box (-10, 20, -5, 30)), false); EXPECT_EQ (interact (poly, db::Box (-10, 100, -5, 110)), false); EXPECT_EQ (interact (poly, db::Box (-10, 100, 0, 110)), true); EXPECT_EQ (interact (poly, db::Box (-10, 100, 5, 110)), true); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Box (-10, 100, 5, 110)), true); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Box (-10, -10, 110, 110)), true); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Box (-10, -10, 50, 110)), true); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Box ()), false); EXPECT_EQ (interact (db::Polygon (), db::Box (-10, -10, 50, 110)), false); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, -10, -1, -1))), false); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, -10, 0, 0))), true); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, -10, 1, 1))), true); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, -10, 20, 10))), true); EXPECT_EQ (interact (poly, db::Polygon (db::Box (10, 20, 20, 30))), true); EXPECT_EQ (interact (poly, db::Polygon (db::Box (10, 20, 15, 25))), true); EXPECT_EQ (interact (poly, db::Polygon (db::Box (30, 10, 40, 20))), false); EXPECT_EQ (interact (poly, db::Polygon (db::Box (30, 20, 40, 30))), true); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, 20, 0, 30))), true); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, 20, -5, 30))), false); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, 100, -5, 110))), false); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, 100, 0, 110))), true); EXPECT_EQ (interact (poly, db::Polygon (db::Box (-10, 100, 5, 110))), true); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Polygon (db::Box (-10, 100, 5, 110))), true); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Polygon (db::Box (-10, -10, 110, 110))), true); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Polygon (db::Box (-10, -10, 50, 110))), true); EXPECT_EQ (interact (db::Polygon (), db::Polygon (db::Box (-10, -10, 50, 110))), false); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Polygon ()), false); EXPECT_EQ (interact (db::Polygon (db::Box (0, 0, 100, 100)), db::Polygon (db::Box ())), false); EXPECT_EQ (interact (db::Polygon (db::Box (-10, -10, -1, -1)), poly), false); EXPECT_EQ (interact (db::Polygon (db::Box (-10, -10, 0, 0)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (-10, -10, 1, 1)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (-10, -10, 20, 10)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (10, 20, 20, 30)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (10, 20, 15, 25)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (30, 10, 40, 20)), poly), false); EXPECT_EQ (interact (db::Polygon (db::Box (30, 20, 40, 30)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (-10, 20, 0, 30)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (-10, 20, -5, 30)), poly), false); EXPECT_EQ (interact (db::Polygon (db::Box (-10, 100, -5, 110)), poly), false); EXPECT_EQ (interact (db::Polygon (db::Box (-10, 100, 0, 110)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (-10, 100, 5, 110)), poly), true); EXPECT_EQ (interact (db::Polygon (db::Box (-10, 100, 5, 110)), db::Polygon (db::Box (0, 0, 100, 100))), true); EXPECT_EQ (interact (db::Polygon (db::Box (-10, -10, 110, 110)), db::Polygon (db::Box (0, 0, 100, 100))), true); EXPECT_EQ (interact (db::Polygon (db::Box (-10, -10, 50, 110)), db::Polygon (db::Box (0, 0, 100, 100))), true); } TEST(11) { // Simple test for polygon-box interaction (integer coordinates) db::DPolygon poly; db::DPoint p[] = { db::DPoint (0, 100), db::DPoint (100, 100), db::DPoint (0, 0) }; poly.assign_hull (p, p + sizeof (p) / sizeof (p[0])); EXPECT_EQ (interact (db::DBox (0, 0, 100, 100), db::DBox (-10, 100, 5, 110)), true); EXPECT_EQ (interact (db::DBox (0, 0, 100, 100), db::DBox (-10, -10, 110, 110)), true); EXPECT_EQ (interact (db::DBox (0, 0, 100, 100), db::DBox (-10, -10, 50, 110)), true); EXPECT_EQ (interact (db::DBox (0, 0, 100, 100), db::DBox ()), false); EXPECT_EQ (interact (poly, db::DBox (-10, -10, -1, -1)), false); EXPECT_EQ (interact (poly, db::DBox (-10, -10, 0, 0)), true); EXPECT_EQ (interact (poly, db::DBox (-10, -10, 1, 1)), true); EXPECT_EQ (interact (poly, db::DBox (-10, -10, 20, 10)), true); EXPECT_EQ (interact (poly, db::DBox (10, 20, 20, 30)), true); EXPECT_EQ (interact (poly, db::DBox (10, 20, 15, 25)), true); EXPECT_EQ (interact (poly, db::DBox (30, 10, 40, 20)), false); EXPECT_EQ (interact (poly, db::DBox (30, 20, 40, 30)), true); EXPECT_EQ (interact (poly, db::DBox (-10, 20, 0, 30)), true); EXPECT_EQ (interact (poly, db::DBox (-10, 20, -5, 30)), false); EXPECT_EQ (interact (poly, db::DBox (-10, 100, -5, 110)), false); EXPECT_EQ (interact (poly, db::DBox (-10, 100, 0, 110)), true); EXPECT_EQ (interact (poly, db::DBox (-10, 100, 5, 110)), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DBox (-10, 100, 5, 110)), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DBox (-10, -10, 110, 110)), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DBox (-10, -10, 50, 110)), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DBox ()), false); EXPECT_EQ (interact (db::DPolygon (), db::DBox (-10, -10, 50, 110)), false); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, -10, -1, -1))), false); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, -10, 0, 0))), true); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, -10, 1, 1))), true); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, -10, 20, 10))), true); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (10, 20, 20, 30))), true); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (10, 20, 15, 25))), true); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (30, 10, 40, 20))), false); // That is a numerical problem: this test fails // EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (30, 20, 40, 30))), true); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, 20, 0, 30))), true); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, 20, -5, 30))), false); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, 100, -5, 110))), false); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, 100, 0, 110))), true); EXPECT_EQ (interact (poly, db::DPolygon (db::DBox (-10, 100, 5, 110))), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DPolygon (db::DBox (-10, 100, 5, 110))), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DPolygon (db::DBox (-10, -10, 110, 110))), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DPolygon (db::DBox (-10, -10, 50, 110))), true); EXPECT_EQ (interact (db::DPolygon (), db::DPolygon (db::DBox (-10, -10, 50, 110))), false); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DPolygon ()), false); EXPECT_EQ (interact (db::DPolygon (db::DBox (0, 0, 100, 100)), db::DPolygon (db::DBox ())), false); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, -10, -1, -1)), poly), false); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, -10, 0, 0)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, -10, 1, 1)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, -10, 20, 10)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (10, 20, 20, 30)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (10, 20, 15, 25)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (30, 10, 40, 20)), poly), false); // That is a numerical problem: this test fails // EXPECT_EQ (interact (db::DPolygon (db::DBox (30, 20, 40, 30)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, 20, 0, 30)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, 20, -5, 30)), poly), false); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, 100, -5, 110)), poly), false); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, 100, 0, 110)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, 100, 5, 110)), poly), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, 100, 5, 110)), db::DPolygon (db::DBox (0, 0, 100, 100))), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, -10, 110, 110)), db::DPolygon (db::DBox (0, 0, 100, 100))), true); EXPECT_EQ (interact (db::DPolygon (db::DBox (-10, -10, 50, 110)), db::DPolygon (db::DBox (0, 0, 100, 100))), true); } TEST(12) { // Simple test for polygon-box interaction (integer coordinates) db::Polygon poly; db::Point p[] = { db::Point (3595000+960,3812000+680), db::Point (3595000+960,3812000+1080), db::Point (3595000+680,3812000+1080), db::Point (3595000+680,3812000+1320), db::Point (3595000+1720,3812000+1320), db::Point (3595000+1720,3812000+1080), db::Point (3595000+1240,3812000+1080), db::Point (3595000+1240,3812000+680) }; poly.assign_hull (p, p + sizeof (p) / sizeof (p[0])); db::Polygon poly2; db::Point p2[] = { db::Point (3595000+660-1000,3812000+480-1000), db::Point (3595000+660-1000,3812000+520), db::Point (3595000+480,3812000+520), db::Point (3595000+480,3812000+880), db::Point (3595000+760,3812000+880), db::Point (3595000+760,3812000+520), db::Point (3595000+1460,3812000+520), db::Point (3595000+1460,3812000+830), db::Point (3595000+1720,3812000+830), db::Point (3595000+1720,3812000+520), db::Point (3595000+1940,3812000+520), db::Point (3595000+1940,3812000+480-1000) }; poly2.assign_hull (p2, p2 + sizeof (p2) / sizeof (p2[0])); EXPECT_EQ (interact (poly, poly2), false); EXPECT_EQ (interact (poly2, poly), false); } static std::string am_to_string (const db::AreaMap &am) { std::string r; for (size_t i = 0; i < am.ny (); ++i) { if (i > 0) { r += ","; } r += "("; for (size_t j = 0; j < am.nx (); ++j) { if (j > 0) { r += ","; } r += tl::to_string (am.get (j, i)); } r += ")"; } return r; } TEST(20) { db::Box box (100, 100, 500, 500); db::Polygon in (box); db::AreaMap am (db::Point (0, 0), db::Vector (200, 200), 3, 3); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(10000,20000,10000),(20000,40000,20000),(10000,20000,10000)"); } TEST(21) { db::Box box (200, 200, 400, 400); db::Polygon in (box); db::AreaMap am (db::Point (0, 0), db::Vector (200, 200), 3, 3); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(0,0,0),(0,40000,0),(0,0,0)"); } TEST(22) { db::Box box (250, 250, 350, 350); db::Polygon in (box); db::AreaMap am (db::Point (0, 0), db::Vector (200, 200), 3, 3); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(0,0,0),(0,10000,0),(0,0,0)"); } TEST(23) { db::Box box (-1000, -500, 2000, 3000); db::Polygon in (box); db::AreaMap am (db::Point (0, 0), db::Vector (200, 200), 3, 3); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(40000,40000,40000),(40000,40000,40000),(40000,40000,40000)"); } TEST(24) { db::Point p[3] = { db::Point (0, 100), db::Point (500, 500), db::Point (0, 0) }; db::Polygon in; in.assign_hull (&p[0], &p[3]); db::AreaMap am (db::Point (0, 0), db::Vector (100, 100), 5, 5); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(5000,0,0,0,0),(4000,4750,0,0,0),(0,2250,4000,0,0),(0,0,1000,2750,0),(0,0,0,250,1000)"); EXPECT_EQ (am.total_area (), 25000); } TEST(25) { db::Point p[3] = { db::Point (0, 100), db::Point (600, 500), db::Point (300, 0) }; db::Polygon in; in.assign_hull (&p[0], &p[3]); db::AreaMap am (db::Point (0, 0), db::Vector (100, 100), 5, 5); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(1650,5000,8350,3000,0),(3350,9175,10000,8660,330),(0,825,6650,10000,5000),(0,0,0,3350,8845),(0,0,0,0,825)"); EXPECT_EQ (am.total_area (), 85010); } TEST(26) { db::Point p[10] = { db::Point (0, 300), db::Point (300, 300), db::Point (300, 0), db::Point (100, 0), db::Point (100, 100), db::Point (200, 100), db::Point (200, 200), db::Point (100, 200), db::Point (100, 0), db::Point (0, 0) }; db::Polygon in; in.assign_hull (&p[0], &p[10]); db::AreaMap am (db::Point (0, 0), db::Vector (100, 100), 3, 3); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(10000,10000,10000),(10000,0,10000),(10000,10000,10000)"); } TEST(27) { db::Point p[10] = { db::Point (-100, 400), db::Point (400, 400), db::Point (400, -100), db::Point (100, -100), db::Point (100, 100), db::Point (200, 100), db::Point (200, 200), db::Point (100, 200), db::Point (100, -100), db::Point (-100, -100) }; db::Polygon in; in.assign_hull (&p[0], &p[10]); db::AreaMap am (db::Point (0, 0), db::Vector (100, 100), 3, 3); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(10000,10000,10000),(10000,0,10000),(10000,10000,10000)"); } TEST(28) { db::Point p[10] = { db::Point (-100, 400), db::Point (400, 400), db::Point (400, -100), db::Point (120, -100), db::Point (120, 120), db::Point (180, 120), db::Point (180, 180), db::Point (120, 180), db::Point (120, -100), db::Point (-100, -100) }; db::Polygon in; in.assign_hull (&p[0], &p[10]); db::AreaMap am (db::Point (0, 0), db::Vector (100, 100), 3, 3); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(10000,10000,10000),(10000,6400,10000),(10000,10000,10000)"); } TEST(29) { db::Point p[] = { db::Point (1600,7009), db::Point (1600,7351), db::Point (1335,8538), db::Point (1341,8545), db::Point (1669,8545), db::Point (1669,7009) }; db::Polygon in; in.assign_hull (&p[0], &p[sizeof(p)/sizeof(p[0])]); db::AreaMap am (db::Point (1360,7038), db::Vector (60,60), 6, 26); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(0,0,0,0,3600,540),(0,0,0,0,3600,540),(0,0,0,0,3600,540),(0,0,0,0,3600,540),(0,0,0,0,3600,540),(0,0,0,235,3600,540),(0,0,0,1020,3600,540),(0,0,0,1830,3600,540),(0,0,0,2640,3600,540),(0,0,36,3411,3600,540),(0,0,630,3600,3600,540),(0,0,1440,3600,3600,540),(0,0,2250,3600,3600,540),(0,0,3060,3600,3600,540),(0,269,3589,3600,3600,540),(0,1050,3600,3600,3600,540),(0,1860,3600,3600,3600,540),(0,2670,3600,3600,3600,540),(52,3424,3600,3600,3600,540),(690,3600,3600,3600,3600,540),(1470,3600,3600,3600,3600,540),(2280,3600,3600,3600,3600,540),(3090,3600,3600,3600,3600,540),(3592,3600,3600,3600,3600,540),(3600,3600,3600,3600,3600,540),(420,420,420,420,420,63)"); } TEST(30) { db::Point p[] = { db::Point (7161,-9547), db::Point (7128,-9531), db::Point (7128,-9198), db::Point (7398,-9198), db::Point (7398,-8928), db::Point (7668,-8928), db::Point (7668,-8658), db::Point (7938,-8658), db::Point (7938,-8388), db::Point (8208,-8388), db::Point (8208,-8118), db::Point (8478,-8118), db::Point (8478,-7848), db::Point (8748,-7848), db::Point (8748,-7578), db::Point (9045,-7578), db::Point (9061,-7610), db::Point (8951,-7759), db::Point (8550,-8245), db::Point (8121,-8703), db::Point (7661,-9133) }; db::Polygon in; in.assign_hull (&p[0], &p[sizeof(p)/sizeof(p[0])]); db::AreaMap am (db::Point (7128,-9547), db::Vector (81,82), 24, 25); db::rasterize (in, am); EXPECT_EQ (am_to_string (am), "(5418,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(6642,6267,1967,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(6642,6642,6582,3119,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(6642,6642,6642,6642,4317,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(1701,1701,1701,4995,6642,5303,735,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,4428,6642,6642,5952,1127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,4428,6642,6642,6642,6178,1484,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,2430,3645,3645,4644,6642,6355,1859,0,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,2214,6642,6642,6489,2275,0,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,2214,6642,6642,6642,6582,2698,0,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,1863,5589,5589,5589,6642,6632,2994,0,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,6642,6642,6624,2698,0,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,6642,6642,6642,6587,2379,0,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,6642,6642,6642,6642,6537,2111,0,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,891,891,891,4725,6642,6471,1859,0,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,4428,6642,6642,6378,1570,0,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,4428,6642,6642,6642,6166,960,0,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,1890,2835,2835,4104,6642,5617,432,0,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2214,6642,6642,4860,104,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2214,6642,6642,6642,3854,0,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1593,4779,4779,4779,6642,2788,0,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6642,6538,1777,0),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6642,6642,6110,704),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6642,6642,6642,4539),(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,81,81,55)"); } TEST(31) { db::Point pattern [] = { db::Point (0, -100), db::Point (0, -50), db::Point (-100, -75), db::Point (0, 100), db::Point (50, 50), db::Point (100, 75), db::Point (100, 0), db::Point (100, -50) }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); db::Polygon pout = minkowsky_sum (p, db::Edge (db::Point (10, 10), db::Point (210, 110)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-40;-90,-65;10,110;210,210;260,160;310,185;310,60)"); pout = minkowsky_sum (p, db::Edge (db::Point (10, 10), db::Point (10, 110)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-40;-90,-65;-90,35;10,210;60,160;110,185;110,-40)"); pout = minkowsky_sum (p, db::Edge (db::Point (10, 110), db::Point (10, 10)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-40;-90,-65;-90,35;10,210;60,160;110,185;110,-40)"); pout = minkowsky_sum (p, db::Edge (db::Point (10, 10), db::Point (210, 10)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-65;-90,-65;10,110;210,110;235,85;310,85;310,-40;210,-90)"); pout = minkowsky_sum (p, db::Edge (db::Point (210, 10), db::Point (10, 10)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-65;-90,-65;10,110;210,110;235,85;310,85;310,-40;210,-90)"); pout = minkowsky_sum (p, db::Edge (db::Point (10, 10), db::Point (210, -90)), true); EXPECT_EQ (pout.to_string (), "(210,-190;143,-157;110,-165;-90,-65;10,110;85,73;110,85;310,-15;310,-140)"); std::vector c; c.push_back (db::Point (10, 10)); c.push_back (db::Point (10, 110)); c.push_back (db::Point (210, 110)); c.push_back (db::Point (210, 10)); c.push_back (db::Point (10, 10)); pout = minkowsky_sum (p, c, true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-65;-90,-65;-90,35;10,210;210,210;235,185;310,185;310,-40;210,-90)"); c.clear (); c.push_back (db::Point (10, 10)); c.push_back (db::Point (10, 310)); c.push_back (db::Point (510, 310)); c.push_back (db::Point (510, 10)); c.push_back (db::Point (10, 10)); pout = minkowsky_sum (p, c, true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-65;-90,-65;-90,210;110,210;110,110;410,110;410,210;-90,210;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)"); // test hole resolution btw EXPECT_EQ (db::resolve_holes (pout).to_string (), "(10,-90;10,-65;-90,-65;-90,210;110,210;110,110;410,110;410,210;-90,210;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)"); EXPECT_EQ (db::polygon_to_simple_polygon (pout).to_string (), "(10,-90;10,-65;-90,-65;-90,210;110,210;110,110;410,110;410,210;-90,210;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)"); pout = minkowsky_sum (p, c, false); EXPECT_EQ (pout.to_string (), "(10,-90;10,-65;-90,-65;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90/110,110;410,110;410,210;110,210)"); // test hole resolution btw EXPECT_EQ (db::resolve_holes (pout).to_string (), "(10,-90;10,-65;-90,-65;-90,210;110,210;110,110;410,110;410,210;-90,210;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)"); EXPECT_EQ (db::polygon_to_simple_polygon (pout).to_string (), "(10,-90;10,-65;-90,-65;-90,210;110,210;110,110;410,110;410,210;-90,210;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)"); EXPECT_EQ (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (pout)).to_string (), "(10,-90;10,-65;-90,-65;-90,210;110,210;110,110;410,110;410,210;-90,210;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)"); pout = minkowsky_sum (p, db::Box (db::Point (10, 10), db::Point (210, 110)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-65;-90,-65;-90,35;10,210;210,210;235,185;310,185;310,-40;210,-90)"); pout = minkowsky_sum (p, db::Box (db::Point (10, 10), db::Point (510, 310)), false); EXPECT_EQ (pout.to_string (), "(10,-90;10,-65;-90,-65;-90,235;10,410;510,410;535,385;610,385;610,-40;510,-90)"); } TEST(32) { db::Point pattern [] = { db::Point (0, -100), db::Point (0, -50), db::Point (-100, -75), db::Point (0, 100), db::Point (50, 50), db::Point (100, 75), db::Point (100, 0), db::Point (100, -50) }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); db::Point hole [] = { db::Point (20, -67), db::Point (20, -30), db::Point (15, -26), db::Point (-60, -45), db::Point (4, 68), db::Point (46, 26), db::Point (80, 43), db::Point (80, -37) }; p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); db::Polygon pout = minkowsky_sum (p, db::Edge (db::Point (10, 10), db::Point (30, 10)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-45;-70,-65;-90,-65;-15,65;27,65;-27,-29;25,-16;45,-16;50,-20;50,-47;90,-27;90,43;76,36;56,36;27,65;-15,65;-8,78;10,110;30,110;73,67;110,85;130,85;130,-40;30,-90)"); pout = minkowsky_sum (p, db::Edge (db::Point (10, 10), db::Point (110, 110)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-40;-90,-65;-8,78;10,110;110,210;160,160;210,185;210,60;110,-40)"); pout = minkowsky_sum (p, db::Edge (db::Point (10, 10), db::Point (50, 10)), true); EXPECT_EQ (pout.to_string (), "(10,-90;10,-50;-50,-65;-90,-65;-23,52;40,52;-3,-23;25,-16;65,-16;70,-20;70,-37;90,-27;90,36;56,36;40,52;-23,52;-8,78;10,110;50,110;87,73;110,85;150,85;150,-40;50,-90)"); } // smoothing TEST(100) { db::Point pattern [] = { db::Point (0, -100), db::Point (0, 0), db::Point (50, 10), db::Point (100, -10), db::Point (150, 0), db::Point (150, -100), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); EXPECT_EQ (smooth (p, 5).to_string (), "(0,-100;0,0;50,10;100,-10;150,0;150,-100)"); EXPECT_EQ (smooth (p, 20).to_string (), "(0,-100;0,0;150,0;150,-100)"); } // smoothing TEST(101) { db::Point pattern [] = { db::Point (0, 0), db::Point (50, 10), db::Point (100, -10), db::Point (150, 0), db::Point (150, 100), db::Point (0, 100), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); EXPECT_EQ (smooth (p, 5).to_string (), "(100,-10;50,10;0,0;0,100;150,100;150,0)"); EXPECT_EQ (smooth (p, 20).to_string (), "(0,0;0,100;150,100;150,0)"); } // smoothing TEST(102) { db::Point pattern [] = { db::Point (0, 0), db::Point (50, 10), db::Point (100, -10), db::Point (150, 0), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); EXPECT_EQ (smooth (p, 20).to_string (), "()"); EXPECT_EQ (smooth (p, 5).to_string (), "(100,-10;150,0;0,0;50,10)"); } // smoothing TEST(103) { db::Point pattern [] = { db::Point (56852, -237283), db::Point (56961, -237258), db::Point (60061, -236492), db::Point (63152, -235686), db::Point (66231, -234839), db::Point (69300, -233952), db::Point (69407, -233919), db::Point (73105, -246382), db::Point (72992, -246417), db::Point (69760, -247351), db::Point (66516, -248243), db::Point (63261, -249092), db::Point (59995, -249899), db::Point (59881, -249925) }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); EXPECT_EQ (smooth (p, 0).to_string (), "(59881,-249925;56852,-237283;56961,-237258;60061,-236492;63152,-235686;66231,-234839;69300,-233952;69407,-233919;73105,-246382;72992,-246417;69760,-247351;66516,-248243;63261,-249092;59995,-249899)"); EXPECT_EQ (smooth (p, 50).to_string (), "(59881,-249925;56852,-237283;63152,-235686;69407,-233919;73105,-246382;69760,-247351)"); EXPECT_EQ (smooth (p, 5000).to_string (), "(59881,-249925;56852,-237283;69407,-233919;73105,-246382)"); } // smoothing TEST(104) { db::Point pattern [] = { db::Point (-245, -942), db::Point (-942, -247), db::Point (-942, -246), db::Point (247, 943), db::Point (248, 943), db::Point (943, 246), db::Point (-244, -942) }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); EXPECT_EQ (smooth (p, 12).to_string (), "(-244,-942;-942,-246;248,943;943,246)"); } // smoothing TEST(105) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 1000), db::Point (100, 1000), db::Point (100, 1100), db::Point (800, 1100), db::Point (800, 1000), db::Point (2000, 1000), db::Point (2000, 0) }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); EXPECT_EQ (smooth (p, 0).to_string (), "(0,0;0,1000;100,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)"); EXPECT_EQ (smooth (p, 50).to_string (), "(0,0;0,1000;100,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)"); EXPECT_EQ (smooth (p, 80).to_string (), "(0,0;0,1000;100,1100;800,1100;800,1000;2000,1000;2000,0)"); EXPECT_EQ (smooth (p, 90).to_string (), "(0,0;100,1100;800,1100;800,1000;2000,1000;2000,0)"); EXPECT_EQ (smooth (p, 100).to_string (), "(0,0;0,1000;2000,1000;2000,0)"); } // rounding TEST(200) { db::Point pattern [] = { db::Point (0, 0), db::Point (100000, 0), db::Point (100000, 100000), db::Point (0, 100000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); { double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 0, 20000, 200); EXPECT_EQ (pp.hull ().size (), 200); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "0"); EXPECT_EQ (tl::to_string (router), "20000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,100000;100000,100000;100000,0)"); } { double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 0, 50000, 200); EXPECT_EQ (pp.hull ().size (), 200); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "0"); EXPECT_EQ (tl::to_string (router), "50000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,100000;100000,100000;100000,0)"); } { double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 0, 70000, 200); EXPECT_EQ (pp.hull ().size (), 200); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "0"); EXPECT_EQ (tl::to_string (router), "50000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,100000;100000,100000;100000,0)"); } } // rounding TEST(201) { db::Point pattern [] = { db::Point (0, 0), db::Point (50000, 0), db::Point (50000, 100000), db::Point (0, 100000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); { double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 0, 50000, 200); EXPECT_EQ (pp.hull ().size (), 200); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "0"); EXPECT_EQ (tl::to_string (router), "25000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,100000;50000,100000;50000,0)"); } } // rounding TEST(202) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 600000), db::Point (400000, 600000), db::Point (400000, 400000), db::Point (600000, 400000), db::Point (600000, 0), }; db::Point hole [] = { db::Point (100000, 100000), db::Point (100000, 500000), db::Point (300000, 500000), db::Point (300000, 300000), db::Point (500000, 300000), db::Point (500000, 100000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); { double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 50000, 150000, 200); EXPECT_EQ (pp.hull ().size (), 300); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "50000"); EXPECT_EQ (tl::to_string (router), "150000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,600000;400000,600000;400000,400000;600000,400000;600000,0/100000,100000;500000,100000;500000,300000;300000,300000;300000,500000;100000,500000)"); } { double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 100000, 150000, 200); EXPECT_EQ (pp.hull ().size (), 300); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "92000"); EXPECT_EQ (tl::to_string (router), "120000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,600000;400000,600000;400000,400000;600000,400000;600000,0/100000,100000;500000,100000;500000,300000;300000,300000;300000,500000;100000,500000)"); } { double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 50000, 150000, 200); db::EdgeProcessor ep; std::vector in, out; in.push_back (pp); ep.simple_merge (in, out, true /*insert cut line*/); pp = out.front (); in.clear (); out.clear (); in.push_back (pp); ep.simple_merge (in, out, false /*no cut line*/); pp = out.front (); EXPECT_EQ (pp.hull ().size (), 301); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "50000"); EXPECT_EQ (tl::to_string (router), "150000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,600000;400000,600000;400000,400000;600000,400000;600000,0/100000,100000;500000,100000;500000,300000;300000,300000;300000,500000;100000,500000)"); } } // rounding TEST(203) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 60000), db::Point (40000, 60000), db::Point (40000, 40000), db::Point (60000, 40000), db::Point (60000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 50000), db::Point (30000, 50000), db::Point (30000, 30000), db::Point (50000, 30000), db::Point (50000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 5000, 15000, 200); db::EdgeProcessor ep; std::vector in, out; in.push_back (pp); ep.simple_merge (in, out, true /*insert cut line*/); pp = out.front (); in.clear (); out.clear (); in.push_back (pp); ep.simple_merge (in, out, false /*no cut line*/); pp = out.front (); pp = smooth (pp, 1); EXPECT_EQ (pp.hull ().size (), 300); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "5000"); EXPECT_EQ (tl::to_string (router), "15000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,60000;40000,60000;40000,40000;60000,40000;60000,0/10000,10000;50000,10000;50000,30000;30000,30000;30000,50000;10000,50000)"); } // rounding TEST(204) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); double rinner = 0.0, router = 0.0; unsigned int n; db::Polygon pr; db::Polygon pp = compute_rounded (p, 10000, 20000, 200); db::EdgeProcessor ep; std::vector in, out; in.push_back (pp); ep.simple_merge (in, out, true /*insert cut line*/); pp = out.front (); in.clear (); out.clear (); in.push_back (pp); ep.simple_merge (in, out, false /*no cut line*/); pp = out.front (); pp = smooth (pp, 1); EXPECT_EQ (pp.hull ().size (), 200); EXPECT_EQ (extract_rad (pp, rinner, router, n, &pr), true); EXPECT_EQ (tl::to_string (rinner), "10000"); EXPECT_EQ (tl::to_string (router), "20000"); EXPECT_EQ (tl::to_string (n), "200"); EXPECT_EQ (pr.to_string (), "(0,0;0,40000;40000,40000;40000,0/10000,10000;30000,10000;30000,30000;10000,30000)"); } // is_convex TEST(300) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); EXPECT_EQ (db::is_convex (p), true); EXPECT_EQ (db::is_convex (db::polygon_to_simple_polygon (p)), true); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); EXPECT_EQ (db::is_convex (p), false); EXPECT_EQ (db::is_convex (db::polygon_to_simple_polygon (p)), false); EXPECT_EQ (db::is_convex (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p))), false); } struct TestPolygonSink : db::SimplePolygonSink { void put (const db::SimplePolygon &p) { if (! s.empty ()) { s += "\n"; } s += p.to_string (); } std::string s; }; // decompose_to_convex TEST(310) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); TestPolygonSink ps; db::decompose_convex (p, db::PO_any, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_any, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); ps.s.clear (); db::decompose_convex (p, db::PO_any, ps); EXPECT_EQ (ps.s, "(0,10000;0,30000;10000,30000;10000,10000)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)" ); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_any, ps); EXPECT_EQ (ps.s, "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(10000,0;10000,10000;40000,10000;40000,0)\n" "(0,0;0,30000;10000,30000;10000,0)" ); ps.s.clear (); db::decompose_convex (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p)), db::PO_any, ps); EXPECT_EQ (ps.s, "(0,10000;0,30000;10000,30000;10000,10000)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)" ); } // decompose_to_convex TEST(311) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); TestPolygonSink ps; db::decompose_convex (p, db::PO_horizontal, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_horizontal, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); ps.s.clear (); db::decompose_convex (p, db::PO_horizontal, ps); EXPECT_EQ (ps.s, "(0,10000;0,30000;10000,30000;10000,10000)\n" "(0,30000;0,40000;40000,40000;40000,30000)\n" "(30000,10000;30000,30000;40000,30000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)" ); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_horizontal, ps); EXPECT_EQ (ps.s, "(0,30000;0,40000;40000,40000;40000,30000)\n" "(30000,10000;30000,30000;40000,30000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)\n" "(0,10000;0,30000;10000,30000;10000,10000)" ); ps.s.clear (); db::decompose_convex (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p)), db::PO_horizontal, ps); EXPECT_EQ (ps.s, "(0,10000;0,30000;10000,30000;10000,10000)\n" "(0,30000;0,40000;40000,40000;40000,30000)\n" "(30000,10000;30000,30000;40000,30000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)" ); } // decompose_to_convex TEST(312) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); TestPolygonSink ps; db::decompose_convex (p, db::PO_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); ps.s.clear (); db::decompose_convex (p, db::PO_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,10000;0,30000;10000,30000;10000,10000)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)" ); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(10000,0;10000,10000;40000,10000;40000,0)\n" "(0,0;0,30000;10000,30000;10000,0)" ); ps.s.clear (); db::decompose_convex (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p)), db::PO_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,10000;0,30000;10000,30000;10000,10000)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)" ); } // decompose_to_convex TEST(313) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); TestPolygonSink ps; db::decompose_convex (p, db::PO_vertical, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_vertical, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); ps.s.clear (); db::decompose_convex (p, db::PO_vertical, ps); EXPECT_EQ (ps.s, "(10000,0;10000,10000;30000,10000;30000,0)\n" "(0,0;0,40000;10000,40000;10000,0)\n" "(10000,30000;10000,40000;30000,40000;30000,30000)\n" "(30000,0;30000,40000;40000,40000;40000,0)" ); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_vertical, ps); EXPECT_EQ (ps.s, "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,0;30000,40000;40000,40000;40000,0)\n" "(10000,0;10000,10000;30000,10000;30000,0)\n" "(0,0;0,30000;10000,30000;10000,0)" ); ps.s.clear (); db::decompose_convex (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p)), db::PO_vertical, ps); EXPECT_EQ (ps.s, "(10000,0;10000,10000;30000,10000;30000,0)\n" "(0,0;0,40000;10000,40000;10000,0)\n" "(10000,30000;10000,40000;30000,40000;30000,30000)\n" "(30000,0;30000,40000;40000,40000;40000,0)" ); } // decompose_to_convex TEST(314) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); TestPolygonSink ps; db::decompose_convex (p, db::PO_vtrapezoids, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_vtrapezoids, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); ps.s.clear (); db::decompose_convex (p, db::PO_vtrapezoids, ps); EXPECT_EQ (ps.s, "(10000,0;10000,10000;30000,10000;30000,0)\n" "(0,0;0,30000;10000,30000;10000,0)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,0;30000,40000;40000,40000;40000,0)" ); ps.s.clear (); db::decompose_convex (db::polygon_to_simple_polygon (p), db::PO_vtrapezoids, ps); EXPECT_EQ (ps.s, "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(10000,0;10000,10000;40000,10000;40000,0)\n" "(0,0;0,30000;10000,30000;10000,0)" ); ps.s.clear (); db::decompose_convex (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p)), db::PO_vtrapezoids, ps); EXPECT_EQ (ps.s, "(10000,0;10000,10000;30000,10000;30000,0)\n" "(0,0;0,30000;10000,30000;10000,0)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,0;30000,40000;40000,40000;40000,0)" ); } // decompose_to_trapezoids TEST(320) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); TestPolygonSink ps; db::decompose_trapezoids (p, db::TD_simple, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); ps.s.clear (); db::decompose_trapezoids (db::polygon_to_simple_polygon (p), db::TD_simple, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); ps.s.clear (); db::decompose_trapezoids (p, db::TD_simple, ps); EXPECT_EQ (ps.s, "(0,0;0,10000;40000,10000;40000,0)\n" "(0,10000;0,30000;10000,30000;10000,10000)\n" "(30000,10000;30000,30000;40000,30000;40000,10000)\n" "(0,30000;0,40000;40000,40000;40000,30000)" ); ps.s.clear (); db::decompose_trapezoids (db::polygon_to_simple_polygon (p), db::TD_simple, ps); EXPECT_EQ (ps.s, "(0,0;0,10000;40000,10000;40000,0)\n" "(0,10000;0,30000;10000,30000;10000,10000)\n" "(30000,10000;30000,30000;40000,30000;40000,10000)\n" "(0,30000;0,40000;40000,40000;40000,30000)" ); ps.s.clear (); db::decompose_trapezoids (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p)), db::TD_simple, ps); EXPECT_EQ (ps.s, "(0,0;0,10000;40000,10000;40000,0)\n" "(0,10000;0,30000;10000,30000;10000,10000)\n" "(30000,10000;30000,30000;40000,30000;40000,10000)\n" "(0,30000;0,40000;40000,40000;40000,30000)" ); } // decompose_to_trapezoids TEST(321) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); TestPolygonSink ps; db::decompose_trapezoids (p, db::TD_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); ps.s.clear (); db::decompose_trapezoids (db::polygon_to_simple_polygon (p), db::TD_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); ps.s.clear (); db::decompose_trapezoids (p, db::TD_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,10000;0,30000;10000,30000;10000,10000)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)" ); ps.s.clear (); db::decompose_trapezoids (db::polygon_to_simple_polygon (p), db::TD_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(10000,0;10000,10000;40000,10000;40000,0)\n" "(0,0;0,30000;10000,30000;10000,0)" ); ps.s.clear (); db::decompose_trapezoids (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p)), db::TD_htrapezoids, ps); EXPECT_EQ (ps.s, "(0,10000;0,30000;10000,30000;10000,10000)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(0,0;0,10000;40000,10000;40000,0)" ); } // decompose_to_trapezoids TEST(322) { db::Point pattern [] = { db::Point (0, 0), db::Point (0, 40000), db::Point (40000, 40000), db::Point (40000, 0), }; db::Point hole [] = { db::Point (10000, 10000), db::Point (10000, 30000), db::Point (30000, 30000), db::Point (30000, 10000), }; db::Polygon p; p.assign_hull (&pattern[0], &pattern[0] + sizeof (pattern) / sizeof (pattern[0])); TestPolygonSink ps; db::decompose_trapezoids (p, db::TD_vtrapezoids, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); ps.s.clear (); db::decompose_trapezoids (db::polygon_to_simple_polygon (p), db::TD_vtrapezoids, ps); EXPECT_EQ (ps.s, "(0,0;0,40000;40000,40000;40000,0)"); p.insert_hole (&hole[0], &hole[0] + sizeof (hole) / sizeof (hole[0])); ps.s.clear (); db::decompose_trapezoids (p, db::TD_vtrapezoids, ps); EXPECT_EQ (ps.s, "(10000,0;10000,10000;30000,10000;30000,0)\n" "(0,0;0,30000;10000,30000;10000,0)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,0;30000,40000;40000,40000;40000,0)" ); ps.s.clear (); db::decompose_trapezoids (db::polygon_to_simple_polygon (p), db::TD_vtrapezoids, ps); EXPECT_EQ (ps.s, "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,10000;30000,40000;40000,40000;40000,10000)\n" "(10000,0;10000,10000;40000,10000;40000,0)\n" "(0,0;0,30000;10000,30000;10000,0)" ); ps.s.clear (); db::decompose_trapezoids (db::simple_polygon_to_polygon (db::polygon_to_simple_polygon (p)), db::TD_vtrapezoids, ps); EXPECT_EQ (ps.s, "(10000,0;10000,10000;30000,10000;30000,0)\n" "(0,0;0,30000;10000,30000;10000,0)\n" "(0,30000;0,40000;30000,40000;30000,30000)\n" "(30000,0;30000,40000;40000,40000;40000,0)" ); }