Skip to content

Commit 98f974b

Browse files
committed
Refactor tolerance and marker bounds check
1 parent cfc7ca9 commit 98f974b

File tree

17 files changed

+108
-206
lines changed

17 files changed

+108
-206
lines changed

src/base/geom/circle.cpp

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,6 @@
77
namespace Geom
88
{
99

10-
Circle::Circle(const Rect &rect, FromRect fromRect)
11-
{
12-
radius = fromRect == FromRect::inscribed
13-
? rect.size.minSize() / 2.0
14-
: fromRect == FromRect::sameWidth ? rect.size.x / 2.0
15-
: fromRect == FromRect::sameHeight ? rect.size.y / 2.0
16-
: fromRect == FromRect::outscribed
17-
? rect.size.diagonal() / 2.0
18-
: throw std::logic_error("invalid circle parameter");
19-
center = rect.pos + rect.size / 2.0;
20-
}
21-
2210
Circle::Circle(const Circle &c0,
2311
const Circle &c1,
2412
double radius,
@@ -40,29 +28,16 @@ bool Circle::concentric(const Circle &c) const
4028
return center == c.center;
4129
}
4230

43-
bool Circle::colateral(const Circle &c, double tolerance) const
44-
{
45-
return Math::AddTolerance(centerDistance(c), tolerance)
46-
== (radius + c.radius);
47-
}
48-
4931
double Circle::area() const { return M_PI * radius * radius; }
5032

51-
bool Circle::overlaps(const Circle &c, double tolerance) const
33+
bool Circle::overlaps(const Circle &c) const
5234
{
5335
auto d = c.center - center;
5436
auto sumRadius = radius + c.radius;
55-
return Math::AddTolerance(d.sqrAbs(), tolerance)
37+
return Math::AddTolerance(d.sqrAbs())
5638
< sumRadius * sumRadius;
5739
}
5840

59-
double Circle::overlapFactor(const Circle &c) const
60-
{
61-
auto d = centerDistance(c);
62-
auto r = radius + c.radius;
63-
return d == 0 ? 0 : r / d;
64-
}
65-
6641
Rect Circle::boundary() const
6742
{
6843
return {center - Point{1, 1} * radius,
@@ -74,6 +49,13 @@ bool Circle::contains(const Point &point) const
7449
return (point - center).sqrAbs() <= radius * radius;
7550
}
7651

52+
double Circle::distance(const Point &point) const
53+
{
54+
return std::max(0.0,
55+
(point - center).abs() - radius,
56+
Math::Floating::less);
57+
}
58+
7759
double Circle::centerDistance(const Circle &c) const
7860
{
7961
return (center - c.center).abs();

src/base/geom/circle.h

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@ namespace Geom
1313
class Circle
1414
{
1515
public:
16-
enum class FromRect {
17-
inscribed,
18-
sameWidth,
19-
sameHeight,
20-
outscribed
21-
};
22-
2316
Point center;
2417
double radius;
2518

@@ -30,8 +23,6 @@ class Circle
3023
radius(radius)
3124
{}
3225

33-
Circle(const Rect &rect, FromRect fromRect);
34-
3526
Circle(const Circle &c0,
3627
const Circle &c1,
3728
double radius,
@@ -48,13 +39,10 @@ class Circle
4839
}
4940

5041
[[nodiscard]] double area() const;
51-
[[nodiscard]] bool overlaps(const Circle &c,
52-
double tolerance) const;
53-
[[nodiscard]] double overlapFactor(const Circle &c) const;
54-
[[nodiscard]] bool colateral(const Circle &c,
55-
double tolerance) const;
42+
[[nodiscard]] bool overlaps(const Circle &c) const;
5643
[[nodiscard]] Rect boundary() const;
5744
[[nodiscard]] bool contains(const Point &point) const;
45+
[[nodiscard]] double distance(const Point &point) const;
5846
[[nodiscard]] double distance(const Circle &c) const;
5947
[[nodiscard]] Solutions<Point, 2> intersection(
6048
const Circle &c) const;

src/base/geom/line.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ struct Line
6161

6262
[[nodiscard]] double distance(const Point &point) const
6363
{
64+
if (isPoint())
65+
return (point - begin).abs();
66+
6467
auto projection = ((point - begin).dot(getDirection()))
6568
/ (length() * length());
6669

src/base/geom/point.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ struct Size : Point
261261
std::min(s1.y, s2.y, less)};
262262
}
263263

264-
[[nodiscard]] bool isSquare(double toleranceFactor = 0.0) const
264+
[[nodiscard]] bool isSquare(double toleranceFactor) const
265265
{
266266
using Math::Floating::is_zero;
267267
if (is_zero(y)) return false;

src/base/geom/quadrilateral.cpp

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,12 @@
77
namespace Geom
88
{
99

10-
ConvexQuad ConvexQuad::Square(Point p0, Point p2)
11-
{
12-
auto center = (p0 + p2) / 2;
13-
auto halfDiagonal = (p2 - p0) / 2;
14-
auto p1 = center + halfDiagonal.normal(false);
15-
auto p3 = center + halfDiagonal.normal(true);
16-
return ConvexQuad({p0, p1, p2, p3});
17-
}
18-
1910
ConvexQuad ConvexQuad::Isosceles(Point base0Middle,
2011
Point base1Middle,
2112
double base0Length,
2213
double base1Length)
2314
{
24-
auto dir = base1Middle == base0Middle
25-
? Point{0, 1}
26-
: (base1Middle - base0Middle).normalized();
15+
auto dir = (base1Middle - base0Middle).normalized();
2716

2817
return ConvexQuad(
2918
{base0Middle + dir.normal(false) * (base0Length / 2),
@@ -32,20 +21,12 @@ ConvexQuad ConvexQuad::Isosceles(Point base0Middle,
3221
base1Middle + dir.normal(false) * (base1Length / 2)});
3322
}
3423

35-
bool ConvexQuad::contains(const Point &p, double tolerance) const
36-
{
37-
auto boundaryArea = Triangle{{points[0], points[1], p}}.area()
38-
+ Triangle{{points[1], points[2], p}}.area()
39-
+ Triangle{{points[2], points[3], p}}.area()
40-
+ Triangle{{points[3], points[0], p}}.area();
41-
42-
return Math::AddTolerance(boundaryArea, tolerance) <= area();
43-
}
44-
45-
double ConvexQuad::area() const
24+
double ConvexQuad::distance(const Point &point) const
4625
{
47-
return Triangle{{points[0], points[1], points[2]}}.area()
48-
+ Triangle{{points[2], points[3], points[0]}}.area();
26+
return std::min(
27+
Triangle{{points[0], points[1], points[2]}}.distance(point),
28+
Triangle{{points[2], points[3], points[0]}}.distance(point),
29+
Math::Floating::less);
4930
}
5031

5132
}

src/base/geom/quadrilateral.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,12 @@ class ConvexQuad
1717

1818
ConvexQuad() = default;
1919
explicit ConvexQuad(const Points &points) : points(points) {}
20-
[[nodiscard]] static ConvexQuad Square(Point p0, Point p2);
2120
[[nodiscard]] static ConvexQuad Isosceles(Point base0Middle,
2221
Point base1Middle,
2322
double base0Length,
2423
double base1Length);
25-
[[nodiscard]] bool contains(const Point &p,
26-
double tolerance = 0.0) const;
27-
[[nodiscard]] double area() const;
24+
25+
[[nodiscard]] double distance(const Point& point) const;
2826
};
2927

3028
}

src/base/geom/rect.cpp

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ namespace Geom
77

88
Rect Rect::Ident() { return {Geom::Point(), Geom::Size::Identity()}; }
99

10-
Rect Rect::CenteredMax()
11-
{
12-
return {Geom::Point::Min() / 2, {Geom::Size::Max()}};
13-
}
14-
1510
Rect Rect::boundary(const Rect &rect) const
1611
{
1712
using Math::Floating::less;
@@ -24,17 +19,6 @@ Rect Rect::boundary(const Rect &rect) const
2419
return res;
2520
}
2621

27-
Rect Rect::boundary(const Point &p) const
28-
{
29-
using Math::Floating::less;
30-
Rect res = positive();
31-
res.setLeft(std::min(res.left(), p.x, less));
32-
res.setBottom(std::min(res.bottom(), p.y, less));
33-
res.setRight(std::max(res.right(), p.x, less));
34-
res.setTop(std::max(res.top(), p.y, less));
35-
return res;
36-
}
37-
3822
Point Rect::normalize(const Point &p) const
3923
{
4024
using Math::Floating::is_zero;

src/base/geom/rect.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#define GEOM_RECT
33

44
#include <array>
5+
#include <functional>
6+
#include <ranges>
57
#include <tuple>
68
#include <vector>
79

@@ -22,10 +24,8 @@ struct Rect
2224
static Rect Boundary(const Container &points);
2325

2426
static Rect Ident();
25-
static Rect CenteredMax();
2627

2728
[[nodiscard]] Rect boundary(const Rect &rect) const;
28-
[[nodiscard]] Rect boundary(const Point &p) const;
2929
[[nodiscard]] Point normalize(const Point &p) const;
3030
[[nodiscard]] Size normalize(const Size &s) const;
3131
[[nodiscard]] Rect normalize(const Rect &rect) const;
@@ -157,9 +157,13 @@ struct Rect
157157
template <class Container>
158158
Rect Rect::Boundary(const Container &points)
159159
{
160-
Rect boundary{points[0]};
161-
for (auto &point : points) boundary = boundary.boundary(point);
162-
return boundary;
160+
auto &&[minx, maxx] = std::ranges::minmax(
161+
std::ranges::views::transform(points, std::mem_fn(&Point::x)),
162+
Math::Floating::less);
163+
auto &&[miny, maxy] = std::ranges::minmax(
164+
std::ranges::views::transform(points, std::mem_fn(&Point::y)),
165+
Math::Floating::less);
166+
return Rect{{minx, miny}, {maxx - minx, maxy - miny}};
163167
}
164168

165169
}

src/base/geom/triangle.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "triangle.h"
22

3+
#include "line.h"
4+
35
namespace Geom
46
{
57

@@ -10,4 +12,22 @@ double Triangle::area() const
1012
return fabs(A ^ B) / 2;
1113
}
1214

15+
double Triangle::distance(const Point &point) const
16+
{
17+
const auto A = points[2] - points[1];
18+
const auto B = points[0] - points[1];
19+
const auto C = points[2] - points[0];
20+
const auto dA = Geom::Line{points[1], points[2]}.distance(point);
21+
const auto dB = Geom::Line{points[0], points[1]}.distance(point);
22+
const auto dC = Geom::Line{points[2], points[0]}.distance(point);
23+
if (const auto double_area = fabs(A ^ B);
24+
!Math::Floating::is_zero(double_area)
25+
&& Math::AddTolerance(
26+
A.abs() * dA + B.abs() * dB + C.abs() * dC)
27+
== double_area) {
28+
return 0.0;
29+
}
30+
return std::min({dA, dB, dC}, Math::Floating::less);
31+
}
32+
1333
}

src/base/geom/triangle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class Triangle
1414
std::array<Point, 3> points;
1515

1616
[[nodiscard]] double area() const;
17+
18+
[[nodiscard]] double distance(const Point& point) const;
1719
};
1820

1921
}

0 commit comments

Comments
 (0)