Skip to content

Commit 855d304

Browse files
committed
Update build_shape function
1 parent 33301f6 commit 855d304

File tree

7 files changed

+128
-88
lines changed

7 files changed

+128
-88
lines changed

include/packingsolver/irregular/shape.hpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,36 @@ struct Shape
212212
const std::string& file_path) const;
213213
};
214214

215-
Shape build_polygon_shape(const std::vector<Point>& points);
215+
struct BuildShapeElement
216+
{
217+
LengthDbl x = 0;
218+
LengthDbl y = 0;
219+
220+
/**
221+
* Type of point:
222+
* - 0: point of the shape
223+
* - 1: center of an anticlockwise circular arc
224+
* - -1: center of a clockwise circular arc
225+
*/
226+
int type = 0;
227+
};
228+
229+
/**
230+
* Function to help build a shape easily.
231+
*
232+
* Espacially useful to write tests.
233+
*
234+
* Examples:
235+
*
236+
* Build a polygon:
237+
*
238+
* Build a right triangle where the hypotenuse is an inflated circular arc
239+
* build_shape({{0, 0}, {1, 0}, {0, 0, 1}, {1, 1}})
240+
*
241+
* Build a right triangle where the hypotenuse is a drilled circular arc
242+
* build_shape({{0, 0}, {1, 0}, {0, 0, -1}, {1, 1}})
243+
*/
244+
Shape build_shape(const std::vector<BuildShapeElement>& points);
216245

217246
double compute_svg_factor(double width);
218247

src/irregular/shape.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -591,18 +591,26 @@ void Shape::write_svg(
591591
file << "</svg>" << std::endl;
592592
}
593593

594-
Shape packingsolver::irregular::build_polygon_shape(
595-
const std::vector<Point>& points)
594+
Shape packingsolver::irregular::build_shape(
595+
const std::vector<BuildShapeElement>& points)
596596
{
597597
Shape shape;
598-
ElementPos pos_prev = points.size() - 1;
598+
Point point_prev = {points.back().x, points.back().y};
599+
bool anticlockwise = false;
600+
Point center = {0, 0};
599601
for (ElementPos pos = 0; pos < (ElementPos)points.size(); ++pos) {
600-
ShapeElement element;
601-
element.type = ShapeElementType::LineSegment;
602-
element.start = points[pos_prev];
603-
element.end = points[pos];
604-
shape.elements.push_back(element);
605-
pos_prev = pos;
602+
const BuildShapeElement point = points[pos];
603+
if (point.type == 0) {
604+
ShapeElement element;
605+
element.type = ShapeElementType::LineSegment;
606+
element.start = point_prev;
607+
element.end = {points[pos].x, points[pos].y};
608+
shape.elements.push_back(element);
609+
point_prev = element.end;
610+
} else {
611+
anticlockwise = (point.type == 1);
612+
center = {points[pos].x, points[pos].y};
613+
}
606614
}
607615
return shape;
608616
}

src/irregular/shape_simplification.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,11 @@ AreaDbl compute_approximation_cost(
203203
return std::numeric_limits<Angle>::infinity();
204204
LengthDbl xp = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denom;
205205
LengthDbl yp = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denom;
206-
AreaDbl cost = shape.copies * build_polygon_shape({
207-
element.element.start,
206+
AreaDbl cost = shape.copies * build_shape({
207+
{element.element.start.x}, {element.element.start.y},
208208
{xp, yp},
209-
element.element.end}).compute_area();
209+
{element.element.end.x, element.element.end.y}
210+
}).compute_area();
210211
if (cost < 0)
211212
return std::numeric_limits<Angle>::infinity();
212213
return cost;
@@ -216,10 +217,11 @@ AreaDbl compute_approximation_cost(
216217
}
217218
} else {
218219
// angle_next < M_PI
219-
Angle cost = shape.copies * build_polygon_shape({
220-
element.element.start,
221-
element_next.element.end,
222-
element.element.end}).compute_area();
220+
Angle cost = shape.copies * build_shape({
221+
{element.element.start.x, element.element.start.y},
222+
{element_next.element.end.x, element_next.element.end.y},
223+
{element.element.end.x, element.element.end.y}
224+
}).compute_area();
223225
if (cost < 0) {
224226
throw std::runtime_error(
225227
"irregular::compute_approximation_cost: outer; "
@@ -257,9 +259,9 @@ AreaDbl compute_approximation_cost(
257259
return std::numeric_limits<Angle>::infinity();
258260
LengthDbl xp = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denom;
259261
LengthDbl yp = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denom;
260-
AreaDbl cost = shape.copies * build_polygon_shape({
261-
element.element.start,
262-
element.element.end,
262+
AreaDbl cost = shape.copies * build_shape({
263+
{element.element.start.x, element.element.start.y},
264+
{element.element.end.x, element.element.end.y},
263265
{xp, yp}}).compute_area();
264266
if (cost < 0)
265267
return std::numeric_limits<Angle>::infinity();
@@ -270,10 +272,11 @@ AreaDbl compute_approximation_cost(
270272
}
271273
} else {
272274
// angle_next < M_PI
273-
Angle cost = shape.copies * build_polygon_shape({
274-
element.element.start,
275-
element.element.end,
276-
element_next.element.end}).compute_area();
275+
Angle cost = shape.copies * build_shape({
276+
{element.element.start.x, element.element.start.y},
277+
{element.element.end.x, element.element.end.y},
278+
{element_next.element.end.x, element_next.element.end.y}
279+
}).compute_area();
277280
if (cost < 0) {
278281
throw std::runtime_error(
279282
"irregular::compute_approximation_cost: inner; "
@@ -380,9 +383,9 @@ void apply_approximation(
380383
}
381384
LengthDbl xp = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denom;
382385
LengthDbl yp = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denom;
383-
AreaDbl cost = build_polygon_shape({
384-
element.element.start,
385-
element.element.end,
386+
AreaDbl cost = build_shape({
387+
{element.element.start.x, element.element.start.y},
388+
{element.element.end.x, element.element.end.y},
386389
{xp, yp}}).compute_area();
387390
element_prev.element.end = {xp, yp};
388391
element_next.element.start = {xp, yp};
@@ -769,7 +772,7 @@ Instance irregular::shape_simplification(
769772
++bin_type_id) {
770773
const BinType& bin_type = instance.bin_type(bin_type_id);
771774
BinType new_bin_type = bin_type;
772-
new_bin_type.shape = build_polygon_shape({
775+
new_bin_type.shape = build_shape({
773776
{bin_type.x_min, bin_type.y_min},
774777
{bin_type.x_max, bin_type.y_min},
775778
{bin_type.x_max, bin_type.y_max},

test/irregular/shape_convex_hull_test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ using namespace packingsolver::irregular;
77

88
TEST(IrregularPolygonConvexHull, Triangle)
99
{
10-
Shape shape = build_polygon_shape({{0, 0}, {3, 0}, {1, 3}});
10+
Shape shape = build_shape({{0, 0}, {3, 0}, {1, 3}});
1111

1212
Shape convex_hull = irregular::convex_hull(shape);
1313

14-
Shape expected_shape = build_polygon_shape({{0, 0}, {3, 0}, {1, 3}});
14+
Shape expected_shape = build_shape({{0, 0}, {3, 0}, {1, 3}});
1515
EXPECT_EQ(expected_shape, convex_hull);
1616
}

test/irregular/shape_self_intersections_removal_test.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using namespace packingsolver::irregular;
77

88
TEST(IrregularShapeSelfIntersectionRemoval, Shape1)
99
{
10-
Shape shape = build_polygon_shape({
10+
Shape shape = build_shape({
1111
{0, 0},
1212
{4, 0},
1313
{4, 4},
@@ -47,7 +47,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape1)
4747

4848
TEST(IrregularShapeSelfIntersectionRemoval, Shape2)
4949
{
50-
Shape shape = build_polygon_shape({
50+
Shape shape = build_shape({
5151
{0, 0},
5252
{4, 0},
5353
{4, 3},
@@ -60,7 +60,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape2)
6060
{0, 3}});
6161
//shape.write_svg("irregular_shape_self_intersection_removal_test_1.svg");
6262

63-
Shape expected_shape = build_polygon_shape({
63+
Shape expected_shape = build_shape({
6464
{0, 0},
6565
{4, 0},
6666
{4, 3},
@@ -73,7 +73,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape2)
7373
{1, 3},
7474
{0, 3}});
7575
std::vector<Shape> expected_holes = {
76-
build_polygon_shape({
76+
build_shape({
7777
{1, 1},
7878
{3, 1},
7979
{2, 2.5}})};
@@ -100,7 +100,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape2)
100100

101101
TEST(IrregularShapeSelfIntersectionRemoval, Shape3)
102102
{
103-
Shape shape = build_polygon_shape({
103+
Shape shape = build_shape({
104104
{0, 0},
105105
{4, 0},
106106
{4, 4},
@@ -113,13 +113,13 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape3)
113113
{0, 4}});
114114
//shape.write_svg("irregular_shape_self_intersection_removal_test_1.svg");
115115

116-
Shape expected_shape = build_polygon_shape({
116+
Shape expected_shape = build_shape({
117117
{0, 0},
118118
{4, 0},
119119
{4, 4},
120120
{0, 4} });
121121
std::vector<Shape> expected_holes = {
122-
build_polygon_shape({
122+
build_shape({
123123
{1, 1},
124124
{3, 1},
125125
{3, 3},
@@ -148,7 +148,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape3)
148148

149149
TEST(IrregularShapeSelfIntersectionRemoval, Shape4)
150150
{
151-
Shape shape = build_polygon_shape({
151+
Shape shape = build_shape({
152152
{0, 0},
153153
{4, 0},
154154
{4, 4},
@@ -161,13 +161,13 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape4)
161161
{0, 4}});
162162
//shape.write_svg("irregular_shape_self_intersection_removal_test_1.svg");
163163

164-
Shape expected_shape = build_polygon_shape({
164+
Shape expected_shape = build_shape({
165165
{0, 0},
166166
{4, 0},
167167
{4, 4},
168168
{0, 4} });
169169
std::vector<Shape> expected_holes = {
170-
build_polygon_shape({
170+
build_shape({
171171
{1, 1},
172172
{3, 1},
173173
{3, 3},
@@ -196,7 +196,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape4)
196196

197197
TEST(IrregularShapeSelfIntersectionRemoval, Shape5)
198198
{
199-
Shape shape = build_polygon_shape({
199+
Shape shape = build_shape({
200200
{0, 0},
201201
{4, 0},
202202
{4, 4},
@@ -210,17 +210,17 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape5)
210210
{0, 4}});
211211
//shape.write_svg("irregular_shape_self_intersection_removal_test_1.svg");
212212

213-
Shape expected_shape = build_polygon_shape({
213+
Shape expected_shape = build_shape({
214214
{0, 0},
215215
{4, 0},
216216
{4, 4},
217217
{0, 4} });
218218
std::vector<Shape> expected_holes = {
219-
build_polygon_shape({
219+
build_shape({
220220
{3, 1},
221221
{3, 3},
222222
{2, 4}}),
223-
build_polygon_shape({
223+
build_shape({
224224
{1, 1},
225225
{2, 4},
226226
{1, 3}})};
@@ -247,7 +247,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape5)
247247

248248
TEST(IrregularShapeSelfIntersectionRemoval, Shape6)
249249
{
250-
Shape shape = build_polygon_shape({
250+
Shape shape = build_shape({
251251
{0, 0},
252252
{4, 0},
253253
{4, 4},
@@ -262,13 +262,13 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape6)
262262
{0, 4}});
263263
//shape.write_svg("irregular_shape_self_intersection_removal_test_1.svg");
264264

265-
Shape expected_shape = build_polygon_shape({
265+
Shape expected_shape = build_shape({
266266
{0, 0},
267267
{4, 0},
268268
{4, 4},
269269
{0, 4} });
270270
std::vector<Shape> expected_holes = {
271-
build_polygon_shape({
271+
build_shape({
272272
{1, 1},
273273
{3, 1},
274274
{3, 3},
@@ -296,7 +296,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape6)
296296

297297
TEST(IrregularShapeSelfIntersectionRemoval, Shape7)
298298
{
299-
Shape shape = build_polygon_shape({
299+
Shape shape = build_shape({
300300
{0, 0},
301301
{4, 0},
302302
{4, 4},
@@ -307,7 +307,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape7)
307307
{0, 4}});
308308
//shape.write_svg("irregular_shape_self_intersection_removal_test_1.svg");
309309

310-
Shape expected_shape = build_polygon_shape({
310+
Shape expected_shape = build_shape({
311311
{0, 0},
312312
{4, 0},
313313
{4, 4},
@@ -336,7 +336,7 @@ TEST(IrregularShapeSelfIntersectionRemoval, Shape7)
336336

337337
TEST(IrregularShapeSelfIntersectionExtractAllHoles, Shape1)
338338
{
339-
Shape hole = build_polygon_shape({
339+
Shape hole = build_shape({
340340
{0, 0},
341341
{4, 0},
342342
{4, 4},
@@ -372,7 +372,7 @@ TEST(IrregularShapeSelfIntersectionExtractAllHoles, Shape1)
372372

373373
TEST(IrregularShapeSelfIntersectionExtractAllHoles, Shape2)
374374
{
375-
Shape hole = build_polygon_shape({
375+
Shape hole = build_shape({
376376
{0, 0},
377377
{4, 0},
378378
{0, 2},
@@ -382,11 +382,11 @@ TEST(IrregularShapeSelfIntersectionExtractAllHoles, Shape2)
382382
//shape.write_svg("irregular_shape_self_intersection_removal_test_1.svg");
383383

384384
std::vector<Shape> expected_holes = {
385-
build_polygon_shape({
385+
build_shape({
386386
{0, 0},
387387
{4, 0},
388388
{2, 1}}),
389-
build_polygon_shape({
389+
build_shape({
390390
{2, 3},
391391
{4, 4},
392392
{0, 4}})};

0 commit comments

Comments
 (0)