Skip to content

Commit 07b6ccd

Browse files
committed
make disjoint() support concave polygons
Signed-off-by: mitukou1109 <mitukou1109@gmail.com>
1 parent 4152ac5 commit 07b6ccd

File tree

3 files changed

+125
-15
lines changed

3 files changed

+125
-15
lines changed

common/autoware_universe_utils/include/autoware/universe_utils/geometry/alt_geometry.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ bool covered_by(const alt::Point2d & point, const alt::PointList2d & ring);
163163

164164
bool covered_by(const alt::Point2d & point, const alt::Polygon2d & poly);
165165

166+
bool disjoint(const alt::Polygon2d & poly1, const alt::Polygon2d & poly2);
167+
166168
bool disjoint(const alt::ConvexPolygon2d & poly1, const alt::ConvexPolygon2d & poly2);
167169

168170
double distance(

common/autoware_universe_utils/src/geometry/alt_geometry.cpp

+6-15
Original file line numberDiff line numberDiff line change
@@ -306,23 +306,14 @@ bool covered_by(const alt::Point2d & point, const alt::Polygon2d & poly)
306306
return covered_by(point, poly.outer());
307307
}
308308

309-
bool disjoint(const alt::ConvexPolygon2d & poly1, const alt::ConvexPolygon2d & poly2)
309+
bool disjoint(const alt::Polygon2d & poly1, const alt::Polygon2d & poly2)
310310
{
311-
if (equals(poly1, poly2)) {
312-
return false;
313-
}
314-
315-
if (intersects(poly1, poly2)) {
316-
return false;
317-
}
318-
319-
for (const auto & vertex : poly1.vertices()) {
320-
if (touches(vertex, poly2)) {
321-
return false;
322-
}
323-
}
311+
return !intersects(poly1, poly2);
312+
}
324313

325-
return true;
314+
bool disjoint(const alt::ConvexPolygon2d & poly1, const alt::ConvexPolygon2d & poly2)
315+
{
316+
return !intersects(poly1, poly2);
326317
}
327318

328319
double distance(

common/autoware_universe_utils/test/src/geometry/test_alt_geometry.cpp

+117
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ TEST(alt_geometry, disjoint)
238238
using autoware::universe_utils::disjoint;
239239
using autoware::universe_utils::alt::ConvexPolygon2d;
240240
using autoware::universe_utils::alt::PointList2d;
241+
using autoware::universe_utils::alt::Polygon2d;
241242

242243
{ // Disjoint
243244
PointList2d vertices1;
@@ -276,6 +277,56 @@ TEST(alt_geometry, disjoint)
276277

277278
EXPECT_FALSE(result);
278279
}
280+
281+
{ // Disjoint (one concave polygon is within the hole of the other)
282+
PointList2d outer1;
283+
outer1.push_back({-1.0, -1.0});
284+
outer1.push_back({-1.0, 3.0});
285+
outer1.push_back({3.0, 3.0});
286+
outer1.push_back({3.0, -1.0});
287+
288+
PointList2d inner1;
289+
inner1.push_back({0.0, 0.0});
290+
inner1.push_back({0.0, 2.0});
291+
inner1.push_back({1.0, 1.0});
292+
inner1.push_back({2.0, 2.0});
293+
inner1.push_back({2.0, 0.0});
294+
295+
PointList2d outer2;
296+
outer2.push_back({0.5, 0.5});
297+
outer2.push_back({0.5, 1.0});
298+
outer2.push_back({1.0, 0.5});
299+
300+
const auto result =
301+
disjoint(Polygon2d::create(outer1, {inner1}).value(), Polygon2d::create(outer2, {}).value());
302+
303+
EXPECT_TRUE(result);
304+
}
305+
306+
{ // Not disjoint (one concave polygon and the hole of the other share a vertex)
307+
PointList2d outer1;
308+
outer1.push_back({-1.0, -1.0});
309+
outer1.push_back({-1.0, 3.0});
310+
outer1.push_back({3.0, 3.0});
311+
outer1.push_back({3.0, -1.0});
312+
313+
PointList2d inner1;
314+
inner1.push_back({0.0, 0.0});
315+
inner1.push_back({0.0, 2.0});
316+
inner1.push_back({1.0, 1.0});
317+
inner1.push_back({2.0, 2.0});
318+
inner1.push_back({2.0, 0.0});
319+
320+
PointList2d outer2;
321+
outer2.push_back({1.0, 1.0});
322+
outer2.push_back({1.5, 0.5});
323+
outer2.push_back({0.5, 0.5});
324+
325+
const auto result =
326+
disjoint(Polygon2d::create(outer1, {inner1}).value(), Polygon2d::create(outer2, {}).value());
327+
328+
EXPECT_FALSE(result);
329+
}
279330
}
280331

281332
TEST(alt_geometry, distance)
@@ -1422,6 +1473,72 @@ TEST(alt_geometry, disjointRand)
14221473
}
14231474
}
14241475

1476+
TEST(alt_geometry, disjointConcaveRand)
1477+
{
1478+
std::vector<autoware::universe_utils::Polygon2d> polygons;
1479+
constexpr auto polygons_nb = 100;
1480+
constexpr auto max_vertices = 10;
1481+
constexpr auto max_values = 1000;
1482+
1483+
autoware::universe_utils::StopWatch<std::chrono::nanoseconds, std::chrono::nanoseconds> sw;
1484+
for (auto vertices = 4UL; vertices < max_vertices; ++vertices) {
1485+
double ground_truth_disjoint_ns = 0.0;
1486+
double ground_truth_not_disjoint_ns = 0.0;
1487+
double alt_disjoint_ns = 0.0;
1488+
double alt_not_disjoint_ns = 0.0;
1489+
int disjoint_count = 0;
1490+
1491+
polygons.clear();
1492+
for (auto i = 0; i < polygons_nb; ++i) {
1493+
polygons.push_back(autoware::universe_utils::random_concave_polygon(vertices, max_values));
1494+
}
1495+
for (auto i = 0UL; i < polygons.size(); ++i) {
1496+
for (auto j = 0UL; j < polygons.size(); ++j) {
1497+
sw.tic();
1498+
const auto ground_truth = boost::geometry::disjoint(polygons[i], polygons[j]);
1499+
if (ground_truth) {
1500+
++disjoint_count;
1501+
ground_truth_disjoint_ns += sw.toc();
1502+
} else {
1503+
ground_truth_not_disjoint_ns += sw.toc();
1504+
}
1505+
1506+
const auto alt_poly1 =
1507+
autoware::universe_utils::alt::Polygon2d::create(polygons[i]).value();
1508+
const auto alt_poly2 =
1509+
autoware::universe_utils::alt::Polygon2d::create(polygons[j]).value();
1510+
sw.tic();
1511+
const auto alt = autoware::universe_utils::disjoint(alt_poly1, alt_poly2);
1512+
if (alt) {
1513+
alt_disjoint_ns += sw.toc();
1514+
} else {
1515+
alt_not_disjoint_ns += sw.toc();
1516+
}
1517+
1518+
if (ground_truth != alt) {
1519+
std::cout << "Failed for the 2 polygons: ";
1520+
std::cout << boost::geometry::wkt(polygons[i]) << boost::geometry::wkt(polygons[j])
1521+
<< std::endl;
1522+
}
1523+
EXPECT_EQ(ground_truth, alt);
1524+
}
1525+
}
1526+
std::printf(
1527+
"polygons_nb = %d, vertices = %ld, %d / %d disjoint pairs\n", polygons_nb, vertices,
1528+
disjoint_count, polygons_nb * polygons_nb);
1529+
std::printf(
1530+
"\tDisjoint:\n\t\tBoost::geometry = %2.2f ms\n\t\tAlt = %2.2f ms\n",
1531+
ground_truth_disjoint_ns / 1e6, alt_disjoint_ns / 1e6);
1532+
std::printf(
1533+
"\tNot disjoint:\n\t\tBoost::geometry = %2.2f ms\n\t\tAlt = %2.2f ms\n",
1534+
ground_truth_not_disjoint_ns / 1e6, alt_not_disjoint_ns / 1e6);
1535+
std::printf(
1536+
"\tTotal:\n\t\tBoost::geometry = %2.2f ms\n\t\tAlt = %2.2f ms\n",
1537+
(ground_truth_not_disjoint_ns + ground_truth_disjoint_ns) / 1e6,
1538+
(alt_not_disjoint_ns + alt_disjoint_ns) / 1e6);
1539+
}
1540+
}
1541+
14251542
TEST(alt_geometry, intersectsRand)
14261543
{
14271544
std::vector<autoware::universe_utils::Polygon2d> polygons;

0 commit comments

Comments
 (0)