UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ExactPredicates.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3// Interface for exact predicates w/ Unreal Engine vector types
4
5#pragma once
6
7#include "CoreMinimal.h"
8#include "Math/MathFwd.h"
9#include "VectorTypes.h"
10
11#include "Misc/CoreMiscDefines.h" // for UE_DEPRECATED
12
13namespace UE {
14namespace Math { template <typename T> struct TVector2; }
15namespace Math { template <typename T> struct TVector; }
16
17namespace Geometry {
18namespace ExactPredicates {
19
20using namespace UE::Math;
21
27
28double GEOMETRYCORE_API Orient2DInexact(const double* PA, const double* PB, const double* PC);
29double GEOMETRYCORE_API Orient2D(const double* PA, const double* PB, const double* PC);
30
31// Specialized version of Orient2D for the case when PC is the origin
32double GEOMETRYCORE_API Orient2DOrigin(double ax, double ay, double bx, double by);
33
34double GEOMETRYCORE_API Orient3DInexact(const double* PA, const double* PB, const double* PC, const double* PD);
35double GEOMETRYCORE_API Orient3D(const double* PA, const double* PB, const double* PC, const double* PD);
36
37double GEOMETRYCORE_API Facing3D(const double* PA, const double* PB, const double* PC, const double* Direction);
38double GEOMETRYCORE_API Facing2D(const double* PA, const double* PB, const double* Direction);
39
40double GEOMETRYCORE_API InCircleInexact(const double* PA, const double* PB, const double* PC, const double* PD);
41double GEOMETRYCORE_API InCircle(const double* PA, const double* PB, const double* PC, const double* PD);
42
43double GEOMETRYCORE_API InSphereInexact(const double* PA, const double* PB, const double* PC, const double* PD, const double* PE);
44double GEOMETRYCORE_API InSphere(const double* PA, const double* PB, const double* PC, const double* PD, const double* PE);
45
46// Note: The float versions of these functions can be marginally faster in some cases,
47// but also are often orders of magnitude slower, and are more likely to fail due to underflow or overflow
48// Consider calling the double versions even for float inputs.
49float GEOMETRYCORE_API Orient2DInexact(const float* PA, const float* PB, const float* PC);
50float GEOMETRYCORE_API Orient2D(const float* PA, const float* PB, const float* PC);
51
52// Specialized version of Orient2D for the case when PC is the origin
53float GEOMETRYCORE_API Orient2DOrigin(float ax, float ay, float bx, float by);
54
55float GEOMETRYCORE_API Orient3DInexact(const float* PA, const float* PB, const float* PC, const float* PD);
56float GEOMETRYCORE_API Orient3D(const float* PA, const float* PB, const float* PC, const float* PD);
57
58float GEOMETRYCORE_API Facing3D(const float* PA, const float* PB, const float* PC, const float* Direction);
59float GEOMETRYCORE_API Facing2D(const float* PA, const float* PB, const float* PC);
60
61float GEOMETRYCORE_API InCircleInexact(const float* PA, const float* PB, const float* PC, const float* PD);
62float GEOMETRYCORE_API InCircle(const float* PA, const float* PB, const float* PC, const float* PD);
63
64// Note: float version of InSphere is not exposed here; instead, convert to and use the double version
65
70template<typename RealType>
72{
73 RealType PA[2]{ A.X, A.Y };
74 RealType PB[2]{ B.X, B.Y };
75 RealType PC[2]{ C.X, C.Y };
76 return Orient2D(PA, PB, PC);
77}
78
79template<typename RealType>
80inline RealType Orient2Origin(const TVector2<RealType>& A, const TVector2<RealType>& B)
81{
82 return Orient2DOrigin(A.X, A.Y, B.X, B.Y);
83}
84
89template<typename RealType>
91{
92 // Note: Though we support computing exact predicates in float precision directly, in practice
93 // it is generally faster and more reliable to compute in double precision
94 double PA[3]{ (double)A.X, (double)A.Y, (double)A.Z };
95 double PB[3]{ (double)B.X, (double)B.Y, (double)B.Z };
96 double PC[3]{ (double)C.X, (double)C.Y, (double)C.Z };
97 double PD[3]{ (double)D.X, (double)D.Y, (double)D.Z };
98 if constexpr (std::is_same_v<RealType, double>)
99 {
100 return Orient3D(PA, PB, PC, PD);
101 }
102 else
103 {
104 // make sure the sign is not lost in casting
105 return (RealType)FMath::Sign(Orient3D(PA, PB, PC, PD));
106 }
107}
108
113template<typename RealType>
114RealType Facing2(const TVector2<RealType>& A, const TVector2<RealType>& B, const TVector2<RealType>& Direction)
115{
116 RealType PA[2]{ A.X, A.Y };
117 RealType PB[2]{ B.X, B.Y };
118 RealType Dir[2]{ Direction.X, Direction.Y };
119 return Facing2D(PA, PB, Dir);
120}
121
126template<typename RealType>
127RealType Facing3(const TVector<RealType>& A, const TVector<RealType>& B, const TVector<RealType>& C, const TVector<RealType>& Direction)
128{
129 // Note: Though we support computing exact predicates in float precision directly, in practice
130 // it is generally faster and more reliable to compute in double precision
131 double PA[3]{ (double)A.X, (double)A.Y, (double)A.Z };
132 double PB[3]{ (double)B.X, (double)B.Y, (double)B.Z };
133 double PC[3]{ (double)C.X, (double)C.Y, (double)C.Z };
134 double Dir[3]{ (double)Direction.X, (double)Direction.Y, (double)Direction.Z };
135 if constexpr (std::is_same_v<RealType, double>)
136 {
137 return Facing3D(PA, PB, PC, Dir);
138 }
139 else
140 {
141 // make sure the sign is not lost in casting
142 return (RealType)FMath::Sign(Facing3D(PA, PB, PC, Dir));
143 }
144}
145
153template<typename RealType>
155{
156 // Note: Though we support computing exact predicates in float precision directly, in practice
157 // it is generally faster and more reliable to compute in double precision
158 double PA[2]{ (double)A.X, (double)A.Y };
159 double PB[2]{ (double)B.X, (double)B.Y };
160 double PC[2]{ (double)C.X, (double)C.Y };
161 double PD[2]{ (double)D.X, (double)D.Y };
162 if constexpr (std::is_same_v<RealType, double>)
163 {
164 return InCircle(PA, PB, PC, PD);
165 }
166 else
167 {
168 // make sure the sign is not lost in casting
169 return (RealType)FMath::Sign(InCircle(PA, PB, PC, PD));
170 }
171}
172
178template<typename RealType>
180{
181 // Note: Though we could compute exact predicates in float precision directly, in practice
182 // it is more reliable and often faster to compute in double precision
183 double PA[3]{ (double)A.X, (double)A.Y, (double)A.Z };
184 double PB[3]{ (double)B.X, (double)B.Y, (double)B.Z };
185 double PC[3]{ (double)C.X, (double)C.Y, (double)C.Z };
186 double PD[3]{ (double)D.X, (double)D.Y, (double)D.Z };
187 double PE[3]{ (double)E.X, (double)E.Y, (double)E.Z };
188 if constexpr (std::is_same_v<RealType, double>)
189 {
190 return InSphere(PA, PB, PC, PD, PE);
191 }
192 else
193 {
194 // make sure the sign is not lost in casting
195 return (RealType)FMath::Sign(InSphere(PA, PB, PC, PD, PE));
196 }
197}
198
199
200}}} // namespace UE::Geometry::ExactPredicates
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
RealType InCircle2(const TVector2< RealType > &A, const TVector2< RealType > &B, const TVector2< RealType > &C, const TVector2< RealType > &D)
Definition ExactPredicates.h:154
double Facing3D(const double *PA, const double *PB, const double *PC, const double *Direction)
Definition ExactPredicates.cpp:50
RealType Facing2(const TVector2< RealType > &A, const TVector2< RealType > &B, const TVector2< RealType > &Direction)
Definition ExactPredicates.h:114
RealType Orient3(const TVector< RealType > &A, const TVector< RealType > &B, const TVector< RealType > &C, const TVector< RealType > &D)
Definition ExactPredicates.h:90
RealType Orient2(const TVector2< RealType > &A, const TVector2< RealType > &B, const TVector2< RealType > &C)
Definition ExactPredicates.h:71
RealType Facing3(const TVector< RealType > &A, const TVector< RealType > &B, const TVector< RealType > &C, const TVector< RealType > &Direction)
Definition ExactPredicates.h:127
double InSphere(const double *PA, const double *PB, const double *PC, const double *PD, const double *PE)
Definition ExactPredicates.cpp:79
double Facing2D(const double *PA, const double *PB, const double *Direction)
Definition ExactPredicates.cpp:56
double Orient2DInexact(const double *pa, const double *pb, const double *pc)
Definition ExactPredicates.cpp:22
double InCircle(const double *PA, const double *PB, const double *PC, const double *PD)
Definition ExactPredicates.cpp:68
double Orient2D(const double *pa, const double *pb, const double *pc)
Definition ExactPredicates.cpp:27
double InSphereInexact(const double *PA, const double *PB, const double *PC, const double *PD, const double *PE)
Definition ExactPredicates.cpp:74
void GlobalInit()
Definition ExactPredicates.cpp:16
double InCircleInexact(const double *PA, const double *PB, const double *PC, const double *PD)
Definition ExactPredicates.cpp:62
double Orient2DOrigin(double ax, double ay, double bx, double by)
Definition ExactPredicates.cpp:33
double Orient3D(const double *PA, const double *PB, const double *PC, const double *PD)
Definition ExactPredicates.cpp:44
double Orient3DInexact(const double *PA, const double *PB, const double *PC, const double *PD)
Definition ExactPredicates.cpp:39
RealType Orient2Origin(const TVector2< RealType > &A, const TVector2< RealType > &B)
Definition ExactPredicates.h:80
RealType InSphere3(const TVector< RealType > &A, const TVector< RealType > &B, const TVector< RealType > &C, const TVector< RealType > &D, const TVector< RealType > &E)
Definition ExactPredicates.h:179
Definition Sphere.cpp:10
Definition AdvancedWidgetsModule.cpp:13
Definition Vector2D.h:38
T Y
Definition Vector2D.h:52
T X
Definition Vector2D.h:49
Definition Vector.h:51
T Z
Definition Vector.h:68
T Y
Definition Vector.h:65
T X
Definition Vector.h:62