UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
DistRay3Segment3.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3// Port of geometry3Sharp DistRay3Segment3
4
5#pragma once
6
7#include "VectorTypes.h"
8#include "SegmentTypes.h"
9
10namespace UE
11{
12namespace Geometry
13{
14
15using namespace UE::Math;
16
20template <typename Real>
22{
23public:
24 // Input
27
28 // Results
29 Real DistanceSquared = -1.0;
30
35
36
42
43 Real Get()
44 {
45 return (Real)sqrt(ComputeResult());
46 }
48 {
49 return ComputeResult();
50 }
51
53 {
54 if (DistanceSquared >= 0)
55 {
56 return DistanceSquared;
57 }
60 double b0 = diff.Dot(Ray.Direction);
61 double b1 = -diff.Dot(Segment.Direction);
62 double c = diff.SquaredLength();
63 double det = TMathUtil<Real>::Abs(1 - a01 * a01);
64 double s0, s1, sqrDist, extDet;
65
67 {
68 // The Ray and Segment are not parallel.
69 s0 = a01 * b1 - b0;
70 s1 = a01 * b0 - b1;
72
73 if (s0 >= 0)
74 {
75 if (s1 >= -extDet)
76 {
77 if (s1 <= extDet) // region 0
78 {
79 // Minimum at interior points of Ray and Segment.
80 double invDet = (1) / det;
81 s0 *= invDet;
82 s1 *= invDet;
83 sqrDist = s0 * (s0 + a01 * s1 + (2) * b0) +
84 s1 * (a01 * s0 + s1 + (2) * b1) + c;
85 }
86 else // region 1
87 {
89 s0 = -(a01 * s1 + b0);
90 if (s0 > 0)
91 {
92 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
93 }
94 else
95 {
96 s0 = 0;
97 sqrDist = s1 * (s1 + (2) * b1) + c;
98 }
99 }
100 }
101 else // region 5
102 {
103 s1 = -Segment.Extent;
104 s0 = -(a01 * s1 + b0);
105 if (s0 > 0)
106 {
107 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
108 }
109 else
110 {
111 s0 = 0;
112 sqrDist = s1 * (s1 + (2) * b1) + c;
113 }
114 }
115 }
116 else
117 {
118 if (s1 <= -extDet) // region 4
119 {
120 s0 = -(-a01 * Segment.Extent + b0);
121 if (s0 > 0)
122 {
123 s1 = -Segment.Extent;
124 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
125 }
126 else
127 {
128 s0 = 0;
129 s1 = -b1;
130 if (s1 < -Segment.Extent)
131 {
132 s1 = -Segment.Extent;
133 }
134 else if (s1 > Segment.Extent)
135 {
136 s1 = Segment.Extent;
137 }
138 sqrDist = s1 * (s1 + (2) * b1) + c;
139 }
140 }
141 else if (s1 <= extDet) // region 3
142 {
143 s0 = 0;
144 s1 = -b1;
145 if (s1 < -Segment.Extent)
146 {
147 s1 = -Segment.Extent;
148 }
149 else if (s1 > Segment.Extent)
150 {
151 s1 = Segment.Extent;
152 }
153 sqrDist = s1 * (s1 + (2) * b1) + c;
154 }
155 else // region 2
156 {
157 s0 = -(a01 * Segment.Extent + b0);
158 if (s0 > 0)
159 {
160 s1 = Segment.Extent;
161 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
162 }
163 else
164 {
165 s0 = 0;
166 s1 = -b1;
167 if (s1 < -Segment.Extent)
168 {
169 s1 = -Segment.Extent;
170 }
171 else if (s1 > Segment.Extent)
172 {
173 s1 = Segment.Extent;
174 }
175 sqrDist = s1 * (s1 + (2) * b1) + c;
176 }
177 }
178 }
179 }
180 else
181 {
182 // Ray and Segment are parallel.
183 if (a01 > 0)
184 {
185 // Opposite direction vectors.
186 s1 = -Segment.Extent;
187 }
188 else
189 {
190 // Same direction vectors.
191 s1 = Segment.Extent;
192 }
193
194 s0 = -(a01 * s1 + b0);
195 if (s0 > 0)
196 {
197 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
198 }
199 else
200 {
201 s0 = 0;
202 sqrDist = s1 * (s1 + (2) * b1) + c;
203 }
204 }
205
210
211 // Account for numerical round-off errors.
212 if (sqrDist < (Real)0)
213 {
214 sqrDist = (Real)0;
215 }
217
218 return sqrDist;
219 }
220
221
222
223
224
226 Real& RayParam, Real& SegParam)
227 {
230 double b0 = diff.Dot(Ray.Direction);
231 double b1 = -diff.Dot(Segment.Direction);
232 double c = diff.SquaredLength();
233 double det = TMathUtil<Real>::Abs(1 - a01 * a01);
234 double s0, s1, sqrDist, extDet;
235
237 {
238 // The Ray and Segment are not parallel.
239 s0 = a01 * b1 - b0;
240 s1 = a01 * b0 - b1;
242
243 if (s0 >= 0)
244 {
245 if (s1 >= -extDet)
246 {
247 if (s1 <= extDet) // region 0
248 {
249 // Minimum at interior points of Ray and Segment.
250 double invDet = (1) / det;
251 s0 *= invDet;
252 s1 *= invDet;
253 sqrDist = s0 * (s0 + a01 * s1 + (2) * b0) +
254 s1 * (a01 * s0 + s1 + (2) * b1) + c;
255 }
256 else // region 1
257 {
258 s1 = Segment.Extent;
259 s0 = -(a01 * s1 + b0);
260 if (s0 > 0)
261 {
262 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
263 }
264 else
265 {
266 s0 = 0;
267 sqrDist = s1 * (s1 + (2) * b1) + c;
268 }
269 }
270 }
271 else // region 5
272 {
273 s1 = -Segment.Extent;
274 s0 = -(a01 * s1 + b0);
275 if (s0 > 0)
276 {
277 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
278 }
279 else
280 {
281 s0 = 0;
282 sqrDist = s1 * (s1 + (2) * b1) + c;
283 }
284 }
285 }
286 else
287 {
288 if (s1 <= -extDet) // region 4
289 {
290 s0 = -(-a01 * Segment.Extent + b0);
291 if (s0 > 0)
292 {
293 s1 = -Segment.Extent;
294 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
295 }
296 else
297 {
298 s0 = 0;
299 s1 = -b1;
300 if (s1 < -Segment.Extent)
301 {
302 s1 = -Segment.Extent;
303 }
304 else if (s1 > Segment.Extent)
305 {
306 s1 = Segment.Extent;
307 }
308 sqrDist = s1 * (s1 + (2) * b1) + c;
309 }
310 }
311 else if (s1 <= extDet) // region 3
312 {
313 s0 = 0;
314 s1 = -b1;
315 if (s1 < -Segment.Extent)
316 {
317 s1 = -Segment.Extent;
318 }
319 else if (s1 > Segment.Extent)
320 {
321 s1 = Segment.Extent;
322 }
323 sqrDist = s1 * (s1 + (2) * b1) + c;
324 }
325 else // region 2
326 {
327 s0 = -(a01 * Segment.Extent + b0);
328 if (s0 > 0)
329 {
330 s1 = Segment.Extent;
331 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
332 }
333 else
334 {
335 s0 = 0;
336 s1 = -b1;
337 if (s1 < -Segment.Extent)
338 {
339 s1 = -Segment.Extent;
340 }
341 else if (s1 > Segment.Extent)
342 {
343 s1 = Segment.Extent;
344 }
345 sqrDist = s1 * (s1 + (2) * b1) + c;
346 }
347 }
348 }
349 }
350 else {
351 // Ray and Segment are parallel.
352 if (a01 > 0)
353 {
354 // Opposite direction vectors.
355 s1 = -Segment.Extent;
356 }
357 else
358 {
359 // Same direction vectors.
360 s1 = Segment.Extent;
361 }
362
363 s0 = -(a01 * s1 + b0);
364 if (s0 > 0)
365 {
366 sqrDist = -s0 * s0 + s1 * (s1 + (2) * b1) + c;
367 }
368 else
369 {
370 s0 = 0;
371 sqrDist = s1 * (s1 + (2) * b1) + c;
372 }
373 }
374
375 RayParam = s0;
376 SegParam = s1;
377
378 // Account for numerical round-off errors.
379 if (sqrDist < 0)
380 {
381 sqrDist = 0;
382 }
383 return sqrDist;
384 }
385
386
387
388
389
390
391
392};
393
396
397} // end namespace UE::Geometry
398} // end namespace UE
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition MathUtil.h:150
static RealType Abs(const RealType Value)
Definition MathUtil.h:215
Definition DistRay3Segment3.h:22
Real DistanceSquared
Definition DistRay3Segment3.h:29
Real GetSquared()
Definition DistRay3Segment3.h:47
TVector< Real > RayClosestPoint
Definition DistRay3Segment3.h:31
static double SquaredDistance(const TRay< Real > &Ray, const TSegment3< Real > &Segment, Real &RayParam, Real &SegParam)
Definition DistRay3Segment3.h:225
Real RayParameter
Definition DistRay3Segment3.h:32
Real ComputeResult()
Definition DistRay3Segment3.h:52
TSegment3< Real > Segment
Definition DistRay3Segment3.h:26
Real Get()
Definition DistRay3Segment3.h:43
Real SegmentParameter
Definition DistRay3Segment3.h:34
TRay< Real > Ray
Definition DistRay3Segment3.h:25
TVector< Real > SegmentClosestPoint
Definition DistRay3Segment3.h:33
TDistRay3Segment3(const TRay< Real > &RayIn, const TSegment3< Real > &SegmentIn)
Definition DistRay3Segment3.h:37
TDistRay3Segment3< double > FDistRay3Segment3d
Definition DistRay3Segment3.h:395
TDistRay3Segment3< float > FDistRay3Segment3f
Definition DistRay3Segment3.h:394
Definition Sphere.cpp:10
Definition AdvancedWidgetsModule.cpp:13
Definition SegmentTypes.h:447
T Extent
Definition SegmentTypes.h:454
TVector< T > Center
Definition SegmentTypes.h:450
TVector< T > Direction
Definition SegmentTypes.h:452
Definition Ray.h:19
TVector< T > Origin
Definition Ray.h:24
TVector< T > Direction
Definition Ray.h:27
Definition Vector.h:51
UE_FORCEINLINE_HINT T Dot(const TVector< T > &V) const
Definition Vector.h:1553