1+ /**
2+ Inochi2D Triangles and trigonometry
3+
4+ Copyright © 2020-2025, Inochi2D Project
5+ Distributed under the 2-Clause BSD License, see LICENSE file.
6+
7+ Authors: Luna Nielsen
8+ */
9+ module inochi2d.core.math.trig ;
10+ import inmath.linalg;
11+
12+ /**
13+ A 2D triangle
14+ */
15+ struct Triangle {
16+ @nogc :
17+ vec2 p1;
18+ vec2 p2;
19+ vec2 p3;
20+
21+ /**
22+ Gets the barycentric coordinates of the given point.
23+
24+ Params:
25+ pt = The point to check.
26+
27+ Returns:
28+ The barycentric coordinates in relation to each
29+ vertex of the triangle.
30+ */
31+ pragma (inline, true )
32+ vec3 barycentric (vec2 pt) nothrow pure {
33+ vec2 v1 = p2 - p1;
34+ vec2 v2 = p3 - p1;
35+ vec2 v3 = pt - p1;
36+ float den = v1.x * v2.y - v2.x * v1.y;
37+ float v = (v3.x * v2.y - v2.x * v3.y) / den;
38+ float w = (v1.x * v3.y - v3.x * v1.y) / den;
39+ return vec3 (
40+ 1.0 - v - w,
41+ v,
42+ w,
43+ );
44+ }
45+
46+ /**
47+ Whether the triangle contains the given point.
48+
49+ Params:
50+ pt = The point to check.
51+
52+ Returns:
53+ $(D true) if the given point lies within this
54+ triangle, $(D false) otherwise.
55+ */
56+ pragma (inline, true )
57+ bool contains (vec2 pt) nothrow pure {
58+ float d1 = sign(pt, p1, p2);
59+ float d2 = sign(pt, p2, p3);
60+ float d3 = sign(pt, p3, p1);
61+ return ! (
62+ ((d1 < 0 ) || (d2 < 0 ) || (d3 < 0 )) &&
63+ ((d1 > 0 ) || (d2 > 0 ) || (d3 > 0 ))
64+ );
65+ }
66+ }
67+
68+ /**
69+ Gets the sign between 3 points.
70+
71+ Params:
72+ p1 = The first point
73+ p2 = The second point
74+ p3 = The third point.
75+
76+ Returns:
77+ A float determining the sign between p1, p2 and p3.
78+ */
79+ pragma (inline, true )
80+ float sign (ref vec2 p1, ref vec2 p2, ref vec2 p3) @nogc nothrow pure {
81+ return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
82+ }
0 commit comments