diff --git a/src/irregular/shape.cpp b/src/irregular/shape.cpp index 1ba2eeda..0e61b57b 100644 --- a/src/irregular/shape.cpp +++ b/src/irregular/shape.cpp @@ -133,12 +133,67 @@ Shape irregular::clean_shape( return shape_new; } +bool irregular::operator==( + const ShapeElement& element_1, + const ShapeElement& element_2) +{ + if (element_1.type != element_2.type) + return false; + if (!(element_1.start == element_2.start)) + return false; + if (!(element_1.end == element_2.end)) + return false; + if (element_1.type == ShapeElementType::CircularArc) { + if (!(element_1.center == element_2.center)) + return false; + if (element_1.anticlockwise != element_2.anticlockwise) + return false; + } + return true; +} + +bool irregular::operator==( + const Shape& shape_1, + const Shape& shape_2) +{ + // First, check if both shapes have the same number of elements. + if (shape_1.elements.size() != shape_2.elements.size()) + return false; + + ElementPos offset = -1; + for (ElementPos element_pos = 0; + element_pos < (ElementPos)shape_2.elements.size(); + ++element_pos) { + if (shape_2.elements[element_pos] == shape_1.elements[0]) { + offset = element_pos; + break; + } + } + if (offset == -1) + return false; + + for (ElementPos element_pos = 0; + element_pos < (ElementPos)shape_2.elements.size(); + ++element_pos) { + if (!(shape_1.elements[element_pos] == shape_2.elements[element_pos + offset])) { + return false; + } + } + + return true; +} + std::vector packingsolver::irregular::borders( const Shape& shape) { std::vector res; auto mm = shape.compute_min_max(); + //std::cout << "mm.first.x " << mm.first.x + // << " mm.first.y " << mm.first.y + // << " mm.second.x " << mm.second.x + // << " mm.second.y " << mm.second.y + // << std::endl; Shape shape_border; ElementPos element_0_pos = 0; @@ -151,6 +206,7 @@ std::vector packingsolver::irregular::borders( break; } } + //std::cout << "element_0_pos " << element_0_pos << std::endl; // 0: left; 1: bottom; 2: right; 3: top. const ShapeElement& element_0 = shape.elements[element_0_pos]; int start_border = (element_0.start.y == mm.first.y)? 1: 0; @@ -159,7 +215,11 @@ std::vector packingsolver::irregular::borders( element_pos < shape.elements.size(); ++element_pos) { const ShapeElement& element = shape.elements[(element_0_pos + element_pos) % shape.elements.size()]; - //std::cout << "element_pos " << ((element_0_pos + element_pos) % bin_type.shape.elements.size()) << " / " << bin_type.shape.elements.size() << ": " << element.to_string() << std::endl; + //std::cout << "element_pos " << ((element_0_pos + element_pos) % shape.elements.size()) + // << " / " << shape.elements.size() + // << ": " << element.to_string() + // << "; start_border: " << start_border + // << std::endl; shape_border.elements.push_back(element); bool close = false; if (start_border == 0) { @@ -170,20 +230,30 @@ std::vector packingsolver::irregular::borders( new_element.end = shape_border.elements[0].start; shape_border.elements.push_back(new_element); close = true; - start_border = 0; + if (!equal(element.end.y, mm.first.y)) { + start_border = 0; + } else { + start_border = 1; + } } else if (equal(element.end.y, mm.first.y)) { - ShapeElement new_element_1; - new_element_1.type = ShapeElementType::LineSegment; - new_element_1.start = element.end; - new_element_1.end = {mm.first.x, mm.first.y}; - shape_border.elements.push_back(new_element_1); - ShapeElement new_element_2; - new_element_2.type = ShapeElementType::LineSegment; - new_element_2.start = new_element_1.end; - new_element_2.end = shape_border.elements[0].start; - shape_border.elements.push_back(new_element_2); + if (element.end.x != shape_border.elements[0].start.x) { + ShapeElement new_element_1; + new_element_1.type = ShapeElementType::LineSegment; + new_element_1.start = element.end; + new_element_1.end = {mm.first.x, mm.first.y}; + shape_border.elements.push_back(new_element_1); + ShapeElement new_element_2; + new_element_2.type = ShapeElementType::LineSegment; + new_element_2.start = new_element_1.end; + new_element_2.end = shape_border.elements[0].start; + shape_border.elements.push_back(new_element_2); + } close = true; - start_border = 1; + if (!equal(element.end.x, mm.second.x)) { + start_border = 1; + } else { + start_border = 2; + } } } else if (start_border == 1) { if (equal(element.end.y, mm.first.y)) { @@ -193,20 +263,30 @@ std::vector packingsolver::irregular::borders( new_element.end = shape_border.elements[0].start; shape_border.elements.push_back(new_element); close = true; - start_border = 1; + if (!equal(element.end.x, mm.second.x)) { + start_border = 1; + } else { + start_border = 2; + } } else if (equal(element.end.x, mm.second.x)) { - ShapeElement new_element_1; - new_element_1.type = ShapeElementType::LineSegment; - new_element_1.start = element.end; - new_element_1.end = {mm.second.x, mm.first.y}; - shape_border.elements.push_back(new_element_1); - ShapeElement new_element_2; - new_element_2.type = ShapeElementType::LineSegment; - new_element_2.start = new_element_1.end; - new_element_2.end = shape_border.elements[0].start; - shape_border.elements.push_back(new_element_2); + if (element.end.y != shape_border.elements[0].start.y) { + ShapeElement new_element_1; + new_element_1.type = ShapeElementType::LineSegment; + new_element_1.start = element.end; + new_element_1.end = {mm.second.x, mm.first.y}; + shape_border.elements.push_back(new_element_1); + ShapeElement new_element_2; + new_element_2.type = ShapeElementType::LineSegment; + new_element_2.start = new_element_1.end; + new_element_2.end = shape_border.elements[0].start; + shape_border.elements.push_back(new_element_2); + } close = true; - start_border = 2; + if (!equal(element.end.y, mm.second.y)) { + start_border = 2; + } else { + start_border = 3; + } } } else if (start_border == 2) { if (equal(element.end.x, mm.second.x)) { @@ -216,20 +296,30 @@ std::vector packingsolver::irregular::borders( new_element.end = shape_border.elements[0].start; shape_border.elements.push_back(new_element); close = true; - start_border = 2; + if (!equal(element.end.y, mm.second.y)) { + start_border = 2; + } else { + start_border = 3; + } } else if (equal(element.end.y, mm.second.y)) { - ShapeElement new_element_1; - new_element_1.type = ShapeElementType::LineSegment; - new_element_1.start = element.end; - new_element_1.end = {mm.second.x, mm.second.y}; - shape_border.elements.push_back(new_element_1); - ShapeElement new_element_2; - new_element_2.type = ShapeElementType::LineSegment; - new_element_2.start = new_element_1.end; - new_element_2.end = shape_border.elements[0].start; - shape_border.elements.push_back(new_element_2); + if (element.end.y != shape_border.elements[0].start.y) { + ShapeElement new_element_1; + new_element_1.type = ShapeElementType::LineSegment; + new_element_1.start = element.end; + new_element_1.end = {mm.second.x, mm.second.y}; + shape_border.elements.push_back(new_element_1); + ShapeElement new_element_2; + new_element_2.type = ShapeElementType::LineSegment; + new_element_2.start = new_element_1.end; + new_element_2.end = shape_border.elements[0].start; + shape_border.elements.push_back(new_element_2); + } close = true; - start_border = 3; + if (!equal(element.end.x, mm.second.x)) { + start_border = 3; + } else { + start_border = 0; + } } } else if (start_border == 3) { if (equal(element.end.y, mm.second.y)) { @@ -239,24 +329,36 @@ std::vector packingsolver::irregular::borders( new_element.end = shape_border.elements[0].start; shape_border.elements.push_back(new_element); close = true; - start_border = 3; + if (!equal(element.end.x, mm.first.x)) { + start_border = 3; + } else { + start_border = 0; + } } else if (equal(element.end.x, mm.first.x)) { - ShapeElement new_element_1; - new_element_1.type = ShapeElementType::LineSegment; - new_element_1.start = element.end; - new_element_1.end = {mm.first.x, mm.second.y}; - shape_border.elements.push_back(new_element_1); - ShapeElement new_element_2; - new_element_2.type = ShapeElementType::LineSegment; - new_element_2.start = new_element_1.end; - new_element_2.end = shape_border.elements[0].start; - shape_border.elements.push_back(new_element_2); + if (element.end.x != shape_border.elements[0].start.x) { + ShapeElement new_element_1; + new_element_1.type = ShapeElementType::LineSegment; + new_element_1.start = element.end; + new_element_1.end = {mm.first.x, mm.second.y}; + shape_border.elements.push_back(new_element_1); + ShapeElement new_element_2; + new_element_2.type = ShapeElementType::LineSegment; + new_element_2.start = new_element_1.end; + new_element_2.end = shape_border.elements[0].start; + shape_border.elements.push_back(new_element_2); + } close = true; - start_border = 0; + if (!equal(element.end.y, mm.second.y)) { + start_border = 0; + } else { + start_border = 1; + } } } + //std::cout << "shape_border " << shape_border.to_string(0) << std::endl; // New shape. if (close) { + //std::cout << "close " << shape_border.to_string(0) << std::endl; if (shape_border.elements.size() >= 3) res.push_back(shape_border.reverse()); shape_border.elements.clear(); diff --git a/src/irregular/shape.hpp b/src/irregular/shape.hpp index ccade05d..d5670df2 100644 --- a/src/irregular/shape.hpp +++ b/src/irregular/shape.hpp @@ -22,5 +22,13 @@ Shape clean_shape( std::vector borders( const Shape& shape); +bool operator==( + const ShapeElement& element_1, + const ShapeElement& element_2); + +bool operator==( + const Shape& shape_1, + const Shape& shape_2); + } } diff --git a/test/irregular/shape_test.cpp b/test/irregular/shape_test.cpp index cb2b419c..941e0aa7 100644 --- a/test/irregular/shape_test.cpp +++ b/test/irregular/shape_test.cpp @@ -140,20 +140,86 @@ TEST(IrregularShape, CleanShapeAligned2) EXPECT_EQ(cleaned_shape.elements[2].end.y, 0); } +TEST(IrregularShape, Borders0) +{ + Shape shape = build_polygon_shape({{0, 0}, {1, 0}, {1, 1}, {0, 1}}); + std::vector expected_borders = {}; + + std::vector shape_borders = borders(shape); + for (const Shape& border: shape_borders) + std::cout << border.to_string(0) << std::endl; + + EXPECT_EQ(shape_borders.size(), expected_borders.size()); + for (const Shape& expected_border: expected_borders) { + bool found = true; + for (const Shape& border: shape_borders) + if (border == expected_border) + found = true; + EXPECT_EQ(found, true); + } +} + TEST(IrregularShape, Borders1) { Shape shape = build_polygon_shape({{2, 0}, {3, 1}, {0, 1}}); + std::vector expected_borders = { + build_polygon_shape({{3, 0}, {3, 1}, {2, 0}}), + build_polygon_shape({{0, 0}, {2, 0}, {0, 1}}), + }; + std::vector shape_borders = borders(shape); + for (const Shape& border: shape_borders) + std::cout << border.to_string(0) << std::endl; - EXPECT_EQ(shape_borders.size(), 3); + EXPECT_EQ(shape_borders.size(), expected_borders.size()); + for (const Shape& expected_border: expected_borders) { + bool found = true; + for (const Shape& border: shape_borders) + if (border == expected_border) + found = true; + EXPECT_EQ(found, true); + } } TEST(IrregularShape, Borders2) { Shape shape = build_polygon_shape({{0, 0}, {3, 1}, {0, 1}}); + std::vector expected_borders = { + build_polygon_shape({{3, 0}, {3, 1}, {0, 0}}), + }; + + std::vector shape_borders = borders(shape); + for (const Shape& border: shape_borders) + std::cout << border.to_string(0) << std::endl; + + EXPECT_EQ(shape_borders.size(), expected_borders.size()); + for (const Shape& expected_border: expected_borders) { + bool found = true; + for (const Shape& border: shape_borders) + if (border == expected_border) + found = true; + EXPECT_EQ(found, true); + } +} + +TEST(IrregularShape, Borders3) +{ + Shape shape = build_polygon_shape({{0, 0}, {50, 0}, {30, 30}}); + std::vector expected_borders = { + build_polygon_shape({{0, 0}, {0, 30}, {30, 30}}), + build_polygon_shape({{30, 30}, {30, 50}, {0, 50}}), + }; + std::vector shape_borders = borders(shape); for (const Shape& border: shape_borders) std::cout << border.to_string(0) << std::endl; - EXPECT_EQ(shape_borders.size(), 1); + EXPECT_EQ(shape_borders.size(), expected_borders.size()); + for (const Shape& expected_border: expected_borders) { + bool found = true; + for (const Shape& border: shape_borders) + if (border == expected_border) + found = true; + EXPECT_EQ(found, true); + } }