13 Scanner(
const char *str,
size_t len) :
pos_(str),
end_(str +
len) {}
15 bool at_end()
const {
return this->
pos_ == this->
end_; }
18 while (this->pos_ != this->end_ && *this->pos_ ==
' ')
22 bool consume(
char c) {
24 if (this->pos_ != this->end_ && *this->pos_ == c) {
32 bool read_int(int16_t min, int16_t max, int16_t &
out) {
33 bool negative = this->consume(
'-');
36 while (this->pos_ != this->end_ && *this->pos_ >=
'0' && *this->pos_ <=
'9') {
40 value = value * 10 + (*this->
pos_ -
'0');
47 if (value < min || value > max)
49 out =
static_cast<int16_t
>(value);
65 for (uint8_t i = 0; i < this->
count; i++) {
67 if (p.
x < POLYGON_MIN_X || p.
x > POLYGON_MAX_X || p.
y < POLYGON_MIN_Y || p.
y > POLYGON_MAX_Y)
75 for (uint8_t i = 0, j = this->
count - 1; i < this->
count; j = i++) {
78 if ((a.
y >
y) == (b.y >
y))
82 const int32_t dy =
static_cast<int32_t
>(b.y) - a.
y;
83 const int32_t lhs = (
static_cast<int32_t
>(
x) - a.
x) * dy;
84 const int32_t rhs = (
static_cast<int32_t
>(
y) - a.
y) * (
static_cast<int32_t
>(b.x) - a.
x);
85 if (dy > 0 ? lhs < rhs : lhs > rhs)
93 Scanner scanner(str,
len);
94 scanner.skip_spaces();
95 while (!scanner.at_end()) {
96 if (result.
count == MAX_POLYGON_POINTS)
99 if (!scanner.read_int(POLYGON_MIN_X, POLYGON_MAX_X, p.
x) || !scanner.consume(
',') ||
100 !scanner.read_int(POLYGON_MIN_Y, POLYGON_MAX_Y, p.
y))
103 bool separator = scanner.consume(
';');
104 scanner.skip_spaces();
105 if (!separator && !scanner.at_end())
117 for (uint8_t i = 0; i < this->
count; i++) {
118 pos = buf_append_printf(buf, POLYGON_STR_SIZE,
pos,
"%s%d,%d", i == 0 ?
"" :
";", this->
points[i].
x,
std::vector< uint8_t > & out
A polygon in radar coordinates. Trivially copyable so it can be saved to preferences as-is.
void format(char *buf) const
Write the polygon as "x,y;x,y;..." into buf, which must hold at least POLYGON_STR_SIZE bytes.
std::array< Point, MAX_POLYGON_POINTS > points
bool parse(const char *str, size_t len)
Parse "x,y;x,y;..." (mm) into this polygon.
bool is_valid() const
True when the polygon is empty, or has a valid number of points that are all inside the radar area.
bool contains(int16_t x, int16_t y) const
Return whether the point is inside the polygon (even-odd rule). Always false for an empty polygon.