Skip to content

Commit

Permalink
Fix borders function
Browse files Browse the repository at this point in the history
  • Loading branch information
fontanf committed Dec 11, 2024
1 parent 8505283 commit deadd0e
Show file tree
Hide file tree
Showing 3 changed files with 227 additions and 51 deletions.
200 changes: 151 additions & 49 deletions src/irregular/shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Shape> packingsolver::irregular::borders(
const Shape& shape)
{
std::vector<Shape> 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;
Expand All @@ -151,6 +206,7 @@ std::vector<Shape> 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;
Expand All @@ -159,7 +215,11 @@ std::vector<Shape> 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) {
Expand All @@ -170,20 +230,30 @@ std::vector<Shape> 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)) {
Expand All @@ -193,20 +263,30 @@ std::vector<Shape> 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)) {
Expand All @@ -216,20 +296,30 @@ std::vector<Shape> 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)) {
Expand All @@ -239,24 +329,36 @@ std::vector<Shape> 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();
Expand Down
8 changes: 8 additions & 0 deletions src/irregular/shape.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,13 @@ Shape clean_shape(
std::vector<Shape> borders(
const Shape& shape);

bool operator==(
const ShapeElement& element_1,
const ShapeElement& element_2);

bool operator==(
const Shape& shape_1,
const Shape& shape_2);

}
}
70 changes: 68 additions & 2 deletions test/irregular/shape_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Shape> expected_borders = {};

std::vector<Shape> 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<Shape> expected_borders = {
build_polygon_shape({{3, 0}, {3, 1}, {2, 0}}),
build_polygon_shape({{0, 0}, {2, 0}, {0, 1}}),
};

std::vector<Shape> 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<Shape> expected_borders = {
build_polygon_shape({{3, 0}, {3, 1}, {0, 0}}),
};

std::vector<Shape> 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<Shape> expected_borders = {
build_polygon_shape({{0, 0}, {0, 30}, {30, 30}}),
build_polygon_shape({{30, 30}, {30, 50}, {0, 50}}),
};

std::vector<Shape> 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);
}
}

0 comments on commit deadd0e

Please sign in to comment.