diff --git a/src/geometry/Shape.cpp b/src/geometry/Shape.cpp index 61d029c4e2..53545df409 100644 --- a/src/geometry/Shape.cpp +++ b/src/geometry/Shape.cpp @@ -108,8 +108,8 @@ void Shape::makeConvex() for (const auto window : poly | ranges::views::sliding(2)) { - const Point2LL& current = window[0]; - const Point2LL& after = window[1]; + const auto& current = window[0]; + const auto& after = window[1]; if (LinearAlg2D::pointIsLeftOfLine(current, convexified.back(), after) < 0) { @@ -123,6 +123,11 @@ void Shape::makeConvex() convexified.push_back(current); } } + + while (convexified.size() >= 2 && (LinearAlg2D::pointIsLeftOfLine(convexified.back(), convexified[convexified.size() - 2], poly.back()) >= 0)) + { + convexified.pop_back(); + } }; std::sort( diff --git a/tests/GCodeExportTest.cpp b/tests/GCodeExportTest.cpp index 5a631e98a9..d0c6cf06f8 100644 --- a/tests/GCodeExportTest.cpp +++ b/tests/GCodeExportTest.cpp @@ -449,6 +449,8 @@ TEST_F(GCodeExportTest, SwitchExtruderSimple) scene.extruders.emplace_back(0, nullptr); ExtruderTrain& train1 = scene.extruders.back(); + train1.settings_.add("machine_extruder_prestart_code", ""); + train1.settings_.add("machine_extruder_change_duration", "0"); train1.settings_.add("machine_extruder_start_code", ";FIRST EXTRUDER START G-CODE!"); train1.settings_.add("machine_extruder_end_code", ";FIRST EXTRUDER END G-CODE!"); train1.settings_.add("machine_extruder_start_code_duration", "0.0"); @@ -459,6 +461,8 @@ TEST_F(GCodeExportTest, SwitchExtruderSimple) scene.extruders.emplace_back(1, nullptr); ExtruderTrain& train2 = scene.extruders.back(); + train2.settings_.add("machine_extruder_prestart_code", ""); + train2.settings_.add("machine_extruder_change_duration", "0"); train2.settings_.add("machine_extruder_start_code", ";SECOND EXTRUDER START G-CODE!"); train2.settings_.add("machine_extruder_end_code", ";SECOND EXTRUDER END G-CODE!"); train2.settings_.add("machine_extruder_start_code_duration", "0.0"); diff --git a/tests/utils/PolygonTest.cpp b/tests/utils/PolygonTest.cpp index fec93cad6b..888e727a6e 100644 --- a/tests/utils/PolygonTest.cpp +++ b/tests/utils/PolygonTest.cpp @@ -5,12 +5,16 @@ #include +#include +#include + #include #include "geometry/OpenPolyline.h" #include "geometry/SingleShape.h" #include "utils/Coord_t.h" #include "utils/SVG.h" // helper functions +#include "utils/linearAlg2D.h" #include "utils/polygonUtils.h" // helper functions // NOLINTBEGIN(*-magic-numbers) @@ -298,6 +302,40 @@ TEST_F(PolygonTest, convexHullStar) } } +TEST_F(PolygonTest, makeConvexPolygon) +{ + Polygon polygon; + polygon.setPoints({ + { 110139, 106039 }, { 111866, 106001 }, { 114033, 106017 }, { 114409, 106046 }, { 114739, 106087 }, { 114982, 106136 }, { 115131, 106193 }, { 115113, 106326 }, + { 115118, 106460 }, { 114915, 106496 }, { 114540, 106512 }, { 114198, 106505 }, { 112338, 106507 }, { 112045, 106531 }, { 111795, 106577 }, { 111609, 106643 }, + { 111498, 106733 }, { 111495, 109561 }, { 111396, 109642 }, { 111229, 109704 }, { 110997, 109750 }, { 110995, 110250 }, { 111227, 110296 }, { 111395, 110358 }, + { 111494, 110438 }, { 111497, 113260 }, { 111553, 113334 }, { 111686, 113402 }, { 111895, 113457 }, { 112241, 113498 }, { 112582, 113507 }, { 114483, 113512 }, + { 114760, 113535 }, { 114879, 113573 }, { 114869, 113841 }, { 114637, 113904 }, { 114404, 113944 }, { 113970, 113985 }, { 113655, 114001 }, { 112302, 114010 }, + { 109861, 113961 }, { 108134, 113999 }, { 105967, 113983 }, { 105591, 113954 }, { 105261, 113913 }, { 105018, 113864 }, { 104869, 113807 }, { 104887, 113674 }, + { 104882, 113540 }, { 105085, 113504 }, { 105460, 113488 }, { 105796, 113495 }, { 107661, 113493 }, { 107811, 113484 }, { 108086, 113448 }, { 108307, 113392 }, + { 108501, 113294 }, { 108505, 110439 }, { 108604, 110358 }, { 108771, 110296 }, { 109004, 110250 }, { 109005, 109750 }, { 108773, 109704 }, { 108605, 109642 }, + { 108506, 109562 }, { 108506, 106720 }, { 108372, 106613 }, { 108106, 106544 }, { 107900, 106513 }, { 107418, 106493 }, { 105517, 106488 }, { 105240, 106465 }, + { 105121, 106427 }, { 105131, 106159 }, { 105363, 106096 }, { 105596, 106056 }, { 106030, 106015 }, { 106345, 105999 }, { 107698, 105990 }, { 110139, 106039 }, + }); + + auto shape = Shape(polygon); + shape.makeConvex(); + const auto convex_hull = shape[0]; + + // test that all corners are convex + EXPECT_TRUE(LinearAlg2D::pointIsLeftOfLine(convex_hull.front(), convex_hull.back(), convex_hull[1]) < 0); + EXPECT_TRUE(LinearAlg2D::pointIsLeftOfLine(convex_hull.back(), convex_hull[convex_hull.size() - 2], convex_hull.front()) < 0); + + for (const auto window : convex_hull | ranges::views::sliding(3)) + { + const auto& a = window[0]; + const auto& b = window[1]; + const auto& c = window[2]; + + EXPECT_TRUE(LinearAlg2D::pointIsLeftOfLine(b, a, c) < 0); + } +} + /* * Multiple min-x points * the convex hull the point with minimal x value. if there are multiple it might go wrong