UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
IntrTriangle2Triangle2.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3// Port of WildMagic TIntrTriangle2Triangle2
4
5#pragma once
6
7#include "VectorTypes.h"
8#include "TriangleTypes.h"
9#include "VectorUtil.h"
10
11namespace UE
12{
13namespace Geometry
14{
15
16using namespace UE::Math;
17
21template <typename Real>
23{
24protected:
25 // Input
27
28public:
29 // Output
30 int Quantity = 0;
33
38
39 // intersection polygon - this array will always be 6 elements long,
40 // however only the first Quantity vertices will be valid
42
48
50 {
51 return Triangle0;
52 }
54 {
55 return Triangle1;
56 }
67
68 bool Test()
69 {
70 int i0, i1;
72
73 // Test edges of Triangle0 for separation.
74 for (i0 = 0, i1 = 2; i0 < 3; i1 = i0++)
75 {
76 // Test axis V0[i1] + t*perp(V0[i0]-V0[i1]), perp(x,y) = (y,-x).
77 dir.X = Triangle0.V[i0].Y - Triangle0.V[i1].Y;
78 dir.Y = Triangle0.V[i1].X - Triangle0.V[i0].X;
79 if (WhichSide(Triangle1, Triangle0.V[i1], dir) > 0)
80 {
81 // Triangle1 is entirely on positive side of Triangle0 edge.
82 return false;
83 }
84 }
85
86 // Test edges of Triangle1 for separation.
87 for (i0 = 0, i1 = 2; i0 < 3; i1 = i0++)
88 {
89 // Test axis V1[i1] + t*perp(V1[i0]-V1[i1]), perp(x,y) = (y,-x).
90 dir.X = Triangle1.V[i0].Y - Triangle1.V[i1].Y;
91 dir.Y = Triangle1.V[i1].X - Triangle1.V[i0].X;
92 if (WhichSide(Triangle0, Triangle1.V[i1], dir) > 0) {
93 // Triangle0 is entirely on positive side of Triangle1 edge.
94 return false;
95 }
96 }
97
98 return true;
99 }
100
101
102
103
104
106 {
107 Find();
108 return this;
109 }
110
111
112 bool Find()
113 {
115 {
117 }
118
119 // The potential intersection is initialized to Triangle1. The set of
120 // vertices is refined based on clipping against each edge of Triangle0.
121 Quantity = 3;
122 for (int i = 0; i < 3; ++i)
123 {
124 Points[i] = Triangle1.V[i];
125 }
126
127 for (int i1 = 2, i0 = 0; i0 < 3; i1 = i0++)
128 {
129 // Clip against edge <V0[i1],V0[i0]>.
132 Triangle0.V[i0].X - Triangle0.V[i1].X);
133 double c = N.Dot(Triangle0.V[i1]);
134 ClipConvexPolygonAgainstLine(N, c, Quantity, Points);
135 if (Quantity == 0)
136 {
137 // Triangle completely clipped, no intersection occurs.
139 }
140 else if (Quantity == 1)
141 {
143 }
144 else if (Quantity == 2)
145 {
147 }
148 else
149 {
151 }
152 }
153
157 }
158
159
160
161
162 static int WhichSide(const TTriangle2<Real>& V, const TVector2<Real>& P, const TVector2<Real>& D)
163 {
164 // Vertices are projected to the form P+t*D. Return value is +1 if all
165 // t > 0, -1 if all t < 0, 0 otherwise, in which case the line splits the
166 // triangle.
167
168 int positive = 0, negative = 0, zero = 0;
169 for (int i = 0; i < 3; ++i)
170 {
171 double t = D.Dot(V.V[i] - P);
172 if (t > (double)0)
173 {
174 ++positive;
175 }
176 else if (t < (double)0)
177 {
178 ++negative;
179 }
180 else
181 {
182 ++zero;
183 }
184
185 if (positive > 0 && negative > 0)
186 {
187 return 0;
188 }
189 }
190 return (zero == 0 ? (positive > 0 ? 1 : -1) : 0);
191 }
192
193
194private:
195 // quantity, V initially are input polygon vertex count and vertices;
196 // on return, they are the clipped polygon vertex count and vertices
197 static void ClipConvexPolygonAgainstLine(const TVector2<Real>& N, double c, int& quantity, TVector2<Real> V[6])
198 {
199 // The input vertices are assumed to be in counterclockwise order. The
200 // ordering is an invariant of this function.
201
202 // Test on which side of line the vertices are.
203 int positive = 0, negative = 0, pIndex = -1;
204 double test[6];
205 int i;
206 for (i = 0; i < quantity; ++i)
207 {
208 test[i] = N.Dot(V[i]) - c;
209 if (test[i] > (double)0)
210 {
211 positive++;
212 if (pIndex < 0)
213 {
214 pIndex = i;
215 }
216 }
217 else if (test[i] < (double)0)
218 {
219 negative++;
220 }
221 }
222
223 if (positive > 0)
224 {
225 if (negative > 0)
226 {
227 // Line transversely intersects polygon.
228 TVector2<Real> CV[6];
229 int cQuantity = 0, cur, prv;
230 double t;
231
232 if (pIndex > 0)
233 {
234 // First clip vertex on line.
235 cur = pIndex;
236 prv = cur - 1;
237 t = test[cur] / (test[cur] - test[prv]);
238 CV[cQuantity++] = V[cur] + t * (V[prv] - V[cur]);
239
240 // Vertices on positive side of line.
241 while (cur < quantity && test[cur] >(double)0)
242 {
243 CV[cQuantity++] = V[cur++];
244 }
245
246 // Last clip vertex on line.
247 if (cur < quantity)
248 {
249 prv = cur - 1;
250 }
251 else
252 {
253 cur = 0;
254 prv = quantity - 1;
255 }
256 t = test[cur] / (test[cur] - test[prv]);
257 CV[cQuantity++] = V[cur] + t * (V[prv] - V[cur]);
258 }
259 else // pIndex is 0
260 {
261 // Vertices on positive side of line.
262 cur = 0;
263 while (cur < quantity && test[cur] >(double)0)
264 {
265 CV[cQuantity++] = V[cur++];
266 }
267
268 // Last clip vertex on line.
269 prv = cur - 1;
270 t = test[cur] / (test[cur] - test[prv]);
271 CV[cQuantity++] = V[cur] + t * (V[prv] - V[cur]);
272
273 // Skip vertices on negative side.
274 while (cur < quantity && test[cur] <= (double)0)
275 {
276 ++cur;
277 }
278
279 // First clip vertex on line.
280 if (cur < quantity)
281 {
282 prv = cur - 1;
283 t = test[cur] / (test[cur] - test[prv]);
284 CV[cQuantity++] = V[cur] + t * (V[prv] - V[cur]);
285
286 // Vertices on positive side of line.
287 while (cur < quantity && test[cur] >(double)0)
288 {
289 CV[cQuantity++] = V[cur++];
290 }
291 }
292 else
293 {
294 // cur = 0
295 prv = quantity - 1;
296 t = test[0] / (test[0] - test[prv]);
297 CV[cQuantity++] = V[0] + t * (V[prv] - V[0]);
298 }
299 }
300
302 for (int Idx = 0; Idx < cQuantity; Idx++)
303 {
304 V[Idx] = CV[Idx];
305 }
306 }
307 // else polygon fully on positive side of line, nothing to do.
308 }
309 else
310 {
311 // Polygon does not intersect positive side of line, clip all.
312 quantity = 0;
313 }
314 }
315
316
317
318};
319
322
323} // end namespace UE::Geometry
324} // end namespace UE
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
EIntersectionResult
Definition VectorUtil.h:10
EIntersectionType
Definition VectorUtil.h:18
Definition IntrTriangle2Triangle2.h:23
TIntrTriangle2Triangle2(TTriangle2< Real > T0, TTriangle2< Real > T1)
Definition IntrTriangle2Triangle2.h:45
TTriangle2< Real > Triangle1
Definition IntrTriangle2Triangle2.h:26
bool Test()
Definition IntrTriangle2Triangle2.h:68
TVector2< Real > Points[6]
Definition IntrTriangle2Triangle2.h:41
EIntersectionResult Result
Definition IntrTriangle2Triangle2.h:31
void SetTriangle0(const TTriangle2< Real > &Triangle0In)
Definition IntrTriangle2Triangle2.h:57
TIntrTriangle2Triangle2()
Definition IntrTriangle2Triangle2.h:43
bool IsSimpleIntersection()
Definition IntrTriangle2Triangle2.h:34
EIntersectionType Type
Definition IntrTriangle2Triangle2.h:32
TTriangle2< Real > GetTriangle0() const
Definition IntrTriangle2Triangle2.h:49
bool Find()
Definition IntrTriangle2Triangle2.h:112
TTriangle2< Real > Triangle0
Definition IntrTriangle2Triangle2.h:26
int Quantity
Definition IntrTriangle2Triangle2.h:30
TTriangle2< Real > GetTriangle1() const
Definition IntrTriangle2Triangle2.h:53
TIntrTriangle2Triangle2 * Compute()
Definition IntrTriangle2Triangle2.h:105
void SetTriangle1(const TTriangle2< Real > &Triangle1In)
Definition IntrTriangle2Triangle2.h:62
static int WhichSide(const TTriangle2< Real > &V, const TVector2< Real > &P, const TVector2< Real > &D)
Definition IntrTriangle2Triangle2.h:162
TIntrTriangle2Triangle2< double > FIntrTriangle2Triangle2d
Definition IntrTriangle2Triangle2.h:321
TIntrTriangle2Triangle2< float > FIntrTriangle2Triangle2f
Definition IntrTriangle2Triangle2.h:320
Definition Sphere.cpp:10
Definition AdvancedWidgetsModule.cpp:13
Definition TriangleTypes.h:39
TVector2< RealType > V[3]
Definition TriangleTypes.h:40
Definition Vector2D.h:38
T Y
Definition Vector2D.h:52
T Dot(const TVector2< T > &V2) const
Definition Vector2D.h:1123
T X
Definition Vector2D.h:49