diff --git a/testbed/main.cc b/testbed/main.cc index d436c93..8718d28 100644 --- a/testbed/main.cc +++ b/testbed/main.cc @@ -51,13 +51,13 @@ using namespace std; using namespace p2t; -bool ParseFile(string filename, vector& out_polyline, vector>& out_holes, - vector& out_steiner); -std::pair BoundingBox(const std::vector& polyline); +bool ParseFile(string filename, vector& out_polyline, vector>& out_holes, + vector& out_steiner); +std::pair BoundingBox(gsl::span polyline); void GenerateRandomPointDistribution(size_t num_points, double min, double max, - vector& out_polyline, - vector>& out_holes, - vector& out_steiner); + vector& out_polyline, + vector>& out_holes, + vector& out_steiner); void Init(int window_width, int window_height); void ShutDown(int return_code); void MainLoop(const double zoom); @@ -89,24 +89,16 @@ vector triangles; /// Triangle map list map; /// Polylines -vector polyline; -vector> holes; -vector steiner; +vector polyline; +vector> holes; +vector steiner; /// Draw the entire triangle map? bool draw_map = false; /// Create a random distribution of points? bool random_distribution = false; -GLFWwindow* window = NULL; - -template void FreeClear(C& cntr) -{ - for (typename C::iterator it = cntr.begin(); it != cntr.end(); ++it) { - delete *it; - } - cntr.clear(); -} +GLFWwindow* window = nullptr; int main(int argc, char* argv[]) { @@ -187,12 +179,12 @@ int main(int argc, char* argv[]) /* * STEP 2: Add holes or Steiner points */ - for (const auto& hole : holes) { + for (auto& hole : holes) { assert(!hole.empty()); cdt->AddHole(hole); } - for (const auto& s : steiner) { - cdt->AddPoint(s); + for (auto& s : steiner) { + cdt->AddPoint(&s); } /* @@ -206,7 +198,7 @@ int main(int argc, char* argv[]) map = cdt->GetMap(); const size_t points_in_holes = std::accumulate(holes.cbegin(), holes.cend(), size_t(0), - [](size_t cumul, const vector& hole) { return cumul + hole.size(); }); + [](size_t cumul, const vector& hole) { return cumul + hole.size(); }); cout << "Number of primary constrained edges = " << polyline.size() << endl; cout << "Number of holes = " << holes.size() << endl; @@ -222,18 +214,18 @@ int main(int argc, char* argv[]) // Cleanup delete cdt; - FreeClear(polyline); - for (vector& hole : holes) { - FreeClear(hole); + polyline.clear(); + for (vector& hole : holes) { + hole.clear(); } - FreeClear(steiner); + steiner.clear(); ShutDown(0); return 0; } -bool ParseFile(string filename, vector& out_polyline, vector>& out_holes, - vector& out_steiner) +bool ParseFile(string filename, vector& out_polyline, vector>& out_holes, + vector& out_steiner) { enum ParserState { Polyline, @@ -241,7 +233,7 @@ bool ParseFile(string filename, vector& out_polyline, vector* hole = nullptr; + vector* hole = nullptr; try { string line; ifstream myfile(filename); @@ -272,14 +264,14 @@ bool ParseFile(string filename, vector& out_polyline, vectorpush_back(new Point(x, y)); + hole->push_back(Point(x, y)); break; case Steiner: - out_steiner.push_back(new Point(x, y)); + out_steiner.push_back(Point(x, y)); break; default: assert(0); @@ -296,36 +288,36 @@ bool ParseFile(string filename, vector& out_polyline, vector BoundingBox(const std::vector& polyline) +std::pair BoundingBox(gsl::span polyline) { assert(polyline.size() > 0); using Scalar = decltype(p2t::Point::x); Point min(std::numeric_limits::max(), std::numeric_limits::max()); Point max(std::numeric_limits::min(), std::numeric_limits::min()); - for (const Point* point : polyline) { - min.x = std::min(min.x, point->x); - min.y = std::min(min.y, point->y); - max.x = std::max(max.x, point->x); - max.y = std::max(max.y, point->y); + for (const Point& point : polyline) { + min.x = std::min(min.x, point.x); + min.y = std::min(min.y, point.y); + max.x = std::max(max.x, point.x); + max.y = std::max(max.y, point.y); } return std::make_pair(min, max); } void GenerateRandomPointDistribution(size_t num_points, double min, double max, - vector& out_polyline, - vector>& out_holes, vector& out_steiner) + vector& out_polyline, + vector>& out_holes, vector& out_steiner) { - out_polyline.push_back(new Point(min, min)); - out_polyline.push_back(new Point(min, max)); - out_polyline.push_back(new Point(max, max)); - out_polyline.push_back(new Point(max, min)); + out_polyline.push_back(Point(min, min)); + out_polyline.push_back(Point(min, max)); + out_polyline.push_back(Point(max, max)); + out_polyline.push_back(Point(max, min)); max -= (1e-4); min += (1e-4); for (int i = 0; i < num_points; i++) { double x = Random(Fun, min, max); double y = Random(Fun, min, max); - out_steiner.push_back(new Point(x, y)); + out_steiner.push_back(Point(x, y)); } } @@ -440,16 +432,16 @@ void Draw(const double zoom) // green glColor3f(0, 1, 0); - vector*> polylines; + vector*> polylines; polylines.push_back(&polyline); - for (vector& hole : holes) { + for (vector& hole : holes) { polylines.push_back(&hole); } for(int i = 0; i < polylines.size(); i++) { - const vector& poly = *polylines[i]; + const vector& poly = *polylines[i]; glBegin(GL_LINE_LOOP); for(int j = 0; j < poly.size(); j++) { - glVertex2d(poly[j]->x, poly[j]->y); + glVertex2d(poly[j].x, poly[j].y); } glEnd(); } diff --git a/unittest/main.cpp b/unittest/main.cpp index 69c49aa..fcd8602 100644 --- a/unittest/main.cpp +++ b/unittest/main.cpp @@ -15,56 +15,47 @@ BOOST_AUTO_TEST_CASE(BasicTest) { - std::vector polyline{ - new p2t::Point(0, 0), - new p2t::Point(1, 0), - new p2t::Point(1, 1), + std::vector polyline{ + p2t::Point(0, 0), + p2t::Point(1, 0), + p2t::Point(1, 1), }; p2t::CDT cdt{ polyline }; BOOST_CHECK_NO_THROW(cdt.Triangulate()); const auto result = cdt.GetTriangles(); BOOST_REQUIRE_EQUAL(result.size(), 1); - BOOST_CHECK_EQUAL(*result[0]->GetPoint(0), *polyline[0]); - BOOST_CHECK_EQUAL(*result[0]->GetPoint(1), *polyline[1]); - BOOST_CHECK_EQUAL(*result[0]->GetPoint(2), *polyline[2]); + BOOST_CHECK_EQUAL(*result[0]->GetPoint(0), polyline[0]); + BOOST_CHECK_EQUAL(*result[0]->GetPoint(1), polyline[1]); + BOOST_CHECK_EQUAL(*result[0]->GetPoint(2), polyline[2]); BOOST_CHECK(p2t::IsDelaunay(result)); - for (const auto p : polyline) { - delete p; - } } BOOST_AUTO_TEST_CASE(QuadTest) { - std::vector polyline{ new p2t::Point(0, 0), new p2t::Point(0, 1), - new p2t::Point(1, 1), new p2t::Point(1, 0) }; + std::vector polyline{ p2t::Point(0, 0), p2t::Point(0, 1), + p2t::Point(1, 1), p2t::Point(1, 0) }; p2t::CDT cdt{ polyline }; BOOST_CHECK_NO_THROW(cdt.Triangulate()); const auto result = cdt.GetTriangles(); BOOST_REQUIRE_EQUAL(result.size(), 2); BOOST_CHECK(p2t::IsDelaunay(result)); - for (const auto p : polyline) { - delete p; - } } BOOST_AUTO_TEST_CASE(NarrowQuadTest) { // Very narrow quad that used to demonstrate a failure case during // triangulation - std::vector polyline { - new p2t::Point(0.0, 0.0), - new p2t::Point(1.0e-05, 0.0), - new p2t::Point(1.1e-04, 3.0e-07), - new p2t::Point(1.0e-04, 3.0e-07) + std::vector polyline { + p2t::Point(0.0, 0.0), + p2t::Point(1.0e-05, 0.0), + p2t::Point(1.1e-04, 3.0e-07), + p2t::Point(1.0e-04, 3.0e-07) }; p2t::CDT cdt{ polyline }; BOOST_CHECK_NO_THROW(cdt.Triangulate()); const auto result = cdt.GetTriangles(); BOOST_REQUIRE_EQUAL(result.size(), 2); BOOST_CHECK(p2t::IsDelaunay(result)); - for (const auto p : polyline) { - delete p; - } } BOOST_AUTO_TEST_CASE(ConcaveBoundaryTest) @@ -72,23 +63,23 @@ BOOST_AUTO_TEST_CASE(ConcaveBoundaryTest) // Concave-by-less-than-epsilon boundaries used to potentially fail // during triangulation const double eps = 1e-15; // This gave EdgeEvent - null triangle - std::vector polyline { - new p2t::Point(0,0), - new p2t::Point(0.5,eps), - new p2t::Point(1,0), - new p2t::Point(1-eps,0.836541), - new p2t::Point(1,2), - new p2t::Point(.46,1.46+eps), - new p2t::Point(0,1), - new p2t::Point(eps,0.5) + std::vector polyline { + p2t::Point(0,0), + p2t::Point(0.5,eps), + p2t::Point(1,0), + p2t::Point(1-eps,0.836541), + p2t::Point(1,2), + p2t::Point(.46,1.46+eps), + p2t::Point(0,1), + p2t::Point(eps,0.5) }; const double r2o4 = std::sqrt(2.)/4; - std::vector hole { - new p2t::Point(0.5+r2o4,0.5), - new p2t::Point(0.5,0.5+r2o4), - new p2t::Point(0.5-r2o4,0.5), - new p2t::Point(0.5-eps,0.5-r2o4) + std::vector hole { + p2t::Point(0.5+r2o4,0.5), + p2t::Point(0.5,0.5+r2o4), + p2t::Point(0.5-r2o4,0.5), + p2t::Point(0.5-eps,0.5-r2o4) }; std::vector interior_points @@ -104,109 +95,94 @@ BOOST_AUTO_TEST_CASE(ConcaveBoundaryTest) const auto result = cdt.GetTriangles(); BOOST_REQUIRE_EQUAL(result.size(), 18); BOOST_CHECK(p2t::IsDelaunay(result)); - for (const auto p : polyline) { - delete p; - } - for (const auto p : hole) { - delete p; - } } BOOST_AUTO_TEST_CASE(PolygonTest01) { // Reported in issue #10 - std::vector polyline = { - new p2t::Point(-0.388419120000000006598384061363, 0.0368141516905975269002837535481), - new p2t::Point(-0.388419120000000006598384061363, 0.0104235565411950892311665484158), - new p2t::Point(-0.611580879999999993401615938637, 0.0104235565411950892311665484158), - new p2t::Point(-0.611580879999999993401615938637, 0.1483950316905975341796875), - new p2t::Point(-0.578899596898762469621146919962, 0.227294628589359948289683188705), - new p2t::Point(-0.500000000000000000000000000000, 0.259975911690597527581303438637), - new p2t::Point(+0.500000000000000000000000000000, 0.259975911690597527581303438637), - new p2t::Point(+0.578899596898762469621146919962, 0.227294628589359948289683188705), - new p2t::Point(+0.611580879999999993401615938637, 0.1483950316905975341796875), - new p2t::Point(+0.611580879999999993401615938637, 0.0104235565411950614755909327869), - new p2t::Point(+0.388419120000000006598384061363, 0.0104235565411950892311665484158), - new p2t::Point(+0.388419120000000006598384061363, 0.0368141516905975130224959457337) + std::vector polyline = { + p2t::Point(-0.388419120000000006598384061363, 0.0368141516905975269002837535481), + p2t::Point(-0.388419120000000006598384061363, 0.0104235565411950892311665484158), + p2t::Point(-0.611580879999999993401615938637, 0.0104235565411950892311665484158), + p2t::Point(-0.611580879999999993401615938637, 0.1483950316905975341796875), + p2t::Point(-0.578899596898762469621146919962, 0.227294628589359948289683188705), + p2t::Point(-0.500000000000000000000000000000, 0.259975911690597527581303438637), + p2t::Point(+0.500000000000000000000000000000, 0.259975911690597527581303438637), + p2t::Point(+0.578899596898762469621146919962, 0.227294628589359948289683188705), + p2t::Point(+0.611580879999999993401615938637, 0.1483950316905975341796875), + p2t::Point(+0.611580879999999993401615938637, 0.0104235565411950614755909327869), + p2t::Point(+0.388419120000000006598384061363, 0.0104235565411950892311665484158), + p2t::Point(+0.388419120000000006598384061363, 0.0368141516905975130224959457337) }; p2t::CDT cdt{ polyline }; BOOST_CHECK_NO_THROW(cdt.Triangulate()); const auto result = cdt.GetTriangles(); BOOST_REQUIRE_EQUAL(result.size(), 10); - for (const auto p : polyline) { - delete p; - } } BOOST_AUTO_TEST_CASE(PolygonTest02) { // Reported in issue #10 - std::vector polyline = { - new p2t::Point(0.9636984967276516, 0.7676550649687783), - new p2t::Point(0.9636984967276516, -0.7676550649687641), - new p2t::Point(-0.3074475690811459, -0.7676550649687641), - new p2t::Point(0.09401654924378076, -0.2590574983578904), - new p2t::Point(0.10567230819363671, -0.09864698028880525), - new p2t::Point(-0.03901177977841874, -0.028405214140875046), - new p2t::Point(-0.428964921810446, -0.08483619470406722), - new p2t::Point(-0.5128305980156834, -0.12847817634298053), - new p2t::Point(-0.5512747518916774, -0.2148501697175078), - new p2t::Point(-0.5917836778064418, -0.7037530067555622), - new p2t::Point(-0.5520451065921502, -0.7676550649687641), - new p2t::Point(-0.9636984967276516, -0.7676550649687641), - new p2t::Point(-0.9636984967276516, 0.767655064968778) + std::vector polyline = { + p2t::Point(0.9636984967276516, 0.7676550649687783), + p2t::Point(0.9636984967276516, -0.7676550649687641), + p2t::Point(-0.3074475690811459, -0.7676550649687641), + p2t::Point(0.09401654924378076, -0.2590574983578904), + p2t::Point(0.10567230819363671, -0.09864698028880525), + p2t::Point(-0.03901177977841874, -0.028405214140875046), + p2t::Point(-0.428964921810446, -0.08483619470406722), + p2t::Point(-0.5128305980156834, -0.12847817634298053), + p2t::Point(-0.5512747518916774, -0.2148501697175078), + p2t::Point(-0.5917836778064418, -0.7037530067555622), + p2t::Point(-0.5520451065921502, -0.7676550649687641), + p2t::Point(-0.9636984967276516, -0.7676550649687641), + p2t::Point(-0.9636984967276516, 0.767655064968778) }; p2t::CDT cdt{ polyline }; BOOST_CHECK_NO_THROW(cdt.Triangulate()); const auto result = cdt.GetTriangles(); BOOST_REQUIRE_EQUAL(result.size(), 11); - for (const auto p : polyline) { - delete p; - } } BOOST_AUTO_TEST_CASE(PolygonTest03) { // Reported in issue #10 - std::vector polyline = { - new p2t::Point(0.9776422201600001, 0.9776422201599928), - new p2t::Point(0.9776422201599999, -0.977642220160007), - new p2t::Point(-0.12788518519240472, -0.9776422201599928), - new p2t::Point(-0.3913394510746002, -0.33861494064331055), - new p2t::Point(-0.47812835166211676, -0.9776422201599928), - new p2t::Point(-0.9776422201600001, -0.9776422201599928), - new p2t::Point(-0.9776422201600001, 0.977642220160007) + std::vector polyline = { + p2t::Point(0.9776422201600001, 0.9776422201599928), + p2t::Point(0.9776422201599999, -0.977642220160007), + p2t::Point(-0.12788518519240472, -0.9776422201599928), + p2t::Point(-0.3913394510746002, -0.33861494064331055), + p2t::Point(-0.47812835166211676, -0.9776422201599928), + p2t::Point(-0.9776422201600001, -0.9776422201599928), + p2t::Point(-0.9776422201600001, 0.977642220160007) }; p2t::CDT cdt{ polyline }; BOOST_CHECK_NO_THROW(cdt.Triangulate()); const auto result = cdt.GetTriangles(); BOOST_REQUIRE_EQUAL(result.size(), 5); - for (const auto p : polyline) { - delete p; - } } BOOST_AUTO_TEST_CASE(PolygonTest04) { - std::vector polyline { - new p2t::Point(450, 2250), - new p2t::Point(450, 1750), - new p2t::Point(400, 1700), - new p2t::Point(350, 1650), - new p2t::Point(350, 500), - new p2t::Point(1050, 1700) + std::vector polyline { + p2t::Point(450, 2250), + p2t::Point(450, 1750), + p2t::Point(400, 1700), + p2t::Point(350, 1650), + p2t::Point(350, 500), + p2t::Point(1050, 1700) }; - std::vector hole { - new p2t::Point(980, 1636), - new p2t::Point(950, 1600), - new p2t::Point(650, 1230), - new p2t::Point(625, 1247), - new p2t::Point(600, 1250), - new p2t::Point(591, 1350), - new p2t::Point(550, 2050) + std::vector hole { + p2t::Point(980, 1636), + p2t::Point(950, 1600), + p2t::Point(650, 1230), + p2t::Point(625, 1247), + p2t::Point(600, 1250), + p2t::Point(591, 1350), + p2t::Point(550, 2050) }; p2t::CDT cdt{ polyline }; @@ -215,18 +191,12 @@ BOOST_AUTO_TEST_CASE(PolygonTest04) BOOST_CHECK_NO_THROW(cdt.Triangulate()); const auto result = cdt.GetTriangles(); BOOST_REQUIRE_EQUAL(result.size(), 13); - for (const auto p : polyline) { - delete p; - } - for (const auto p : hole) { - delete p; - } } BOOST_AUTO_TEST_CASE(TestbedFilesTest) { for (const auto& filename : { "custom.dat", "diamond.dat", "star.dat", "test.dat" }) { - std::vector polyline; + std::vector polyline; // Load pointset from file // Parse and tokenize data file std::string line; @@ -249,15 +219,12 @@ BOOST_AUTO_TEST_CASE(TestbedFilesTest) std::back_inserter>(tokens)); double x = std::stod(tokens[0]); double y = std::stod(tokens[1]); - polyline.push_back(new p2t::Point(x, y)); + polyline.push_back(p2t::Point(x, y)); } p2t::CDT cdt{ polyline }; BOOST_CHECK_NO_THROW(cdt.Triangulate()); const auto result = cdt.GetTriangles(); BOOST_REQUIRE(result.size() * 3 > polyline.size()); BOOST_CHECK_MESSAGE(p2t::IsDelaunay(result), filename + std::to_string(polyline.size())); - for (const auto p : polyline) { - delete p; - } } }