Skip to content

Commit 0ed1cdf

Browse files
committed
Add check for concave polygon
1 parent 20b584e commit 0ed1cdf

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

util/geometry.hh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include <cstdint>
3+
#include <span>
34

45
struct Rect;
56

@@ -63,3 +64,49 @@ struct Rect {
6364
// {
6465
// return RectC{.left = left, .top = top, .right = right(), .bottom = bottom()};
6566
// }
67+
68+
template<typename T>
69+
constexpr bool is_poly_concave(std::span<const T> points) requires requires(T pt) {
70+
pt.x;
71+
pt.y;
72+
}
73+
{
74+
auto n = points.size();
75+
if (n < 3)
76+
return false;
77+
78+
auto X_prod = [](T O, T A, T B) { return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x); };
79+
80+
int sign = 0;
81+
for (auto i = 0u; i < points.size(); i++) {
82+
auto O = points[i];
83+
auto A = points[(i + 1) % n];
84+
auto B = points[(i + 2) % n];
85+
auto cross = X_prod(O, A, B);
86+
if (cross == 0)
87+
continue;
88+
89+
if (sign == 0)
90+
sign = cross;
91+
92+
if ((sign > 0 && cross < 0) || (sign < 0 && cross > 0))
93+
return true;
94+
}
95+
return false;
96+
}
97+
98+
namespace CpputilGeometry
99+
{
100+
101+
struct TestPoint {
102+
uint8_t x;
103+
uint8_t y;
104+
};
105+
106+
constexpr std::array<TestPoint, 4> tri{{{1, 1}, {2, 1}, {2, 2}, {1, 2}}};
107+
static_assert(is_poly_concave<TestPoint>(tri) == false);
108+
109+
constexpr std::array<TestPoint, 5> cave{{{1, 1}, {2, 1}, {2, 0}, {2, 2}, {1, 2}}};
110+
static_assert(is_poly_concave<TestPoint>(cave) == true);
111+
112+
} // namespace CpputilGeometry

0 commit comments

Comments
 (0)