Skip to content

Commit 563a7c3

Browse files
committed
Fix triangle distance
1 parent 55a54ad commit 563a7c3

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

src/base/geom/line.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ struct Line
1919

2020
[[nodiscard]] bool isPoint() const { return begin == end; }
2121

22-
[[nodiscard]] Geom::Line extend(double length) const
22+
[[nodiscard]] Line extend(double length) const
2323
{
2424
auto p = end - begin;
2525
auto d = p.abs();
@@ -28,28 +28,28 @@ struct Line
2828
return {begin, begin + (p * m)};
2929
}
3030

31-
Geom::Line operator*(double value) const
31+
Line operator*(double value) const
3232
{
3333
return {begin * value, end * value};
3434
}
3535

36-
Geom::Line operator+(const Geom::Line &other) const
36+
Line operator+(const Line &other) const
3737
{
3838
return {begin + other.begin, end + other.end};
3939
}
4040

41-
void shift(const Geom::Point &offset)
41+
void shift(const Point &offset)
4242
{
4343
begin = begin + offset;
4444
end = end + offset;
4545
}
4646

47-
[[nodiscard]] Geom::Point at(double t) const
47+
[[nodiscard]] Point at(double t) const
4848
{
4949
return begin + (end - begin) * t;
5050
}
5151

52-
[[nodiscard]] Geom::Line segment(double t0, double t1) const
52+
[[nodiscard]] Line segment(double t0, double t1) const
5353
{
5454
return {at(t0), at(t1)};
5555
}
@@ -63,7 +63,7 @@ struct Line
6363
{
6464
if (isPoint()) return (point - begin).abs();
6565

66-
auto projection = ((point - begin).dot(getDirection()))
66+
auto projection = (point - begin).dot(getDirection())
6767
/ (length() * length());
6868

6969
projection =

src/base/geom/triangle.cpp

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

3+
#include <compare>
4+
35
#include "line.h"
46

57
namespace Geom
@@ -14,20 +16,27 @@ double Triangle::area() const
1416

1517
double Triangle::distance(const Point &point) const
1618
{
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) {
19+
auto rot_dir = [](const Point &a, const Point &b, const Point &c)
20+
{
21+
return std::weak_order(0.0,
22+
(b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x));
23+
};
24+
25+
using std::is_gteq;
26+
using std::is_lteq;
27+
using std::is_neq;
28+
if (auto r1 = rot_dir(points[0], points[1], point),
29+
r2 = rot_dir(points[1], points[2], point),
30+
r3 = rot_dir(points[2], points[0], point);
31+
(is_neq(r1) || is_neq(r2) || is_neq(r3))
32+
&& ((is_lteq(r1) && is_lteq(r2) && is_lteq(r3))
33+
|| (is_gteq(r1) && is_gteq(r2) && is_gteq(r3))))
2834
return 0.0;
29-
}
30-
return std::min({dA, dB, dC}, Math::Floating::less);
35+
36+
return std::min({Line{points[0], points[1]}.distance(point),
37+
Line{points[1], points[2]}.distance(point),
38+
Line{points[2], points[0]}.distance(point)},
39+
Math::Floating::less);
3140
}
3241

3342
}

0 commit comments

Comments
 (0)