MeshLib C++ Docs
Loading...
Searching...
No Matches
MRInSphere.h
Go to the documentation of this file.
1#pragma once
2
4#include "MRFastInt.h"
5#include "MRPch/MRBindingMacros.h"
6#include <array>
7#include <cassert>
8#include <type_traits>
9#include <utility>
10
11namespace MR
12{
15
16
19
35
42[[nodiscard]] MRMESH_API InSphereResult inSphere( const Vector3i & a, const Vector3i & b, const Vector3i & c,
43 const Vector3i & d, std::int64_t rSq );
44
63[[nodiscard]] MRMESH_API InSphereResult inSphere( const std::array<PreciseVertCoords, 4> & vs, std::int64_t rSq );
64
74template <typename T>
76{
77 static_assert( std::is_floating_point_v<T> );
78public:
84 bool reset( const Vector3<T> & va, const Vector3<T> & vb, const Vector3<T> & vc, T sqRadius )
85 {
86 a = va;
87 rSq = sqRadius;
88 E = -1;
89 u = vb - va;
90 v = vc - va;
91
94 const T uu = u.lengthSq();
95 const T vv = v.lengthSq();
96 if ( uu > 4 * rSq || vv > 4 * rSq || ( v - u ).lengthSq() > 4 * rSq )
97 return false;
98
99 w = cross( u, v );
100 W = w.lengthSq();
101 if ( W <= 0 )
102 return false;
103
105 const T uv = dot( u, v );
106 M = ( vv * ( uu - uv ) ) * u + ( uu * ( vv - uv ) ) * v;
107
109 E = 4 * rSq * W * W - M.lengthSq();
110 return E >= 0;
111 }
112
117 void flip()
118 {
119 assert( E >= 0 );
120 std::swap( u, v );
121 w = -w;
122 }
123
126 [[nodiscard]] InSphereResult operator()( const Vector3<T> & d ) const
127 {
128 assert( E >= 0 );
129 const auto q = d - a;
130
132 const T qq = q.lengthSq();
133 if ( qq > 4 * rSq )
135
136 const T A = W * qq - dot( q, M );
137 const T t = dot( q, w );
138
140 if ( A < 0 && t >= 0 )
142 if ( A >= 0 && t <= 0 )
143 return ( A == 0 && ( t == 0 || E == 0 ) ) ? InSphereResult::OnSphere : InSphereResult::Outside;
144 const T lhs = A * A * W;
145 const T rhs = E * t * t;
146 if ( lhs == rhs )
148 return ( A < 0 ) == ( lhs > rhs ) ? InSphereResult::Inside : InSphereResult::Outside;
149 }
150
151private:
152 Vector3<T> a;
153 Vector3<T> u, v;
154 Vector3<T> w;
155 T W = 0;
156 Vector3<T> M;
157 T E = -1;
158 T rSq = 0;
159};
160
161
164template <>
165class InSphereTester<int>
166{
167public:
173 MRMESH_API bool reset( const Vector3i & a, const Vector3i & b, const Vector3i & c, std::int64_t rSq );
174
179 void flip()
180 {
181 assert( E >= 0 );
182 std::swap( u, v );
183 w = -w;
184 }
185
188 [[nodiscard]] MRMESH_API InSphereResult operator()( const Vector3i & d ) const;
189
190protected:
191 Vector3i a;
192 Vector3i64 u, v;
193 Vector3i64 w;
195 std::array<FastInt<192>, 3> M;
197 std::int64_t rSq = 0;
198};
199
203
207{
208public:
217 MRMESH_API bool reset( const PreciseVertCoords & a, const PreciseVertCoords & b, const PreciseVertCoords & c, std::int64_t rSq );
218
222 void flip()
223 {
225 {
226 std::swap( u, v );
228 }
229 else
231 std::swap( vb_, vc_ );
232 }
233
239 [[nodiscard]] MRMESH_API InSphereResult operator()( const PreciseVertCoords & d ) const;
240
244 [[nodiscard]] bool degenerateTriangle() const { return degenerateTriangle_; }
245
252
254 [[nodiscard]] MR_BIND_IGNORE const Vector3i64 & normal() const { return w; }
255
257 [[nodiscard]] MR_BIND_IGNORE const FastInt<192> & normalSq() const { return W; }
258
262 [[nodiscard]] MR_BIND_IGNORE const FastInt<384> & heightSq() const { return E; }
263
264protected:
266 Vector3i64 pairV_;
267 Vector3i pairPt_;
268 VertId va_, vb_, vc_;
269 int pairSigma_ = 0;
270 bool degenerateTriangle_ = false;
271};
272
277{
278public:
282 MRMESH_API bool reset( const PreciseVertCoords & a, const PreciseVertCoords & b, const PreciseVertCoords & c, std::int64_t rSq );
283
286 void flip()
287 {
289 hn_ = -hn_;
290 }
291
295 [[nodiscard]] MRMESH_API InSphereResult operator()( const PreciseVertCoords & d ) const;
296
304 [[nodiscard]] MRMESH_API bool outsideBothSpheres( const Vector3i & d ) const;
305
306private:
310 Vector3d cc_, hn_;
311
314 double tol_ = 0;
315};
316
320template <typename T>
321[[nodiscard]] std::enable_if_t<std::is_floating_point_v<T>, InSphereResult> inSphere( const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c,
322 const Vector3<T> & d, T rSq )
323{
324 InSphereTester<T> tester;
325 if ( !tester.reset( a, b, c, rSq ) )
327 return tester( d );
328}
329
330MR_BIND_TEMPLATE( InSphereResult inSphere( const Vector3f & a, const Vector3f & b, const Vector3f & c, const Vector3f & d, float rSq ) );
331MR_BIND_TEMPLATE( InSphereResult inSphere( const Vector3d & a, const Vector3d & b, const Vector3d & c, const Vector3d & d, double rSq ) );
332
334
335}
#define MRMESH_API
Definition MRMeshFwd.h:85
#define M(T)
Definition MRInSphere.h:277
Definition MRFastInt.h:141
Definition MRInSphere.h:207
Definition MRInSphere.h:76
bool degenerateTriangle_
reset() got W == 0 with two coincident points and an existing perturbed sphere
Definition MRInSphere.h:270
bool reset(const Vector3i &a, const Vector3i &b, const Vector3i &c, std::int64_t rSq)
bool reset(const PreciseVertCoords &a, const PreciseVertCoords &b, const PreciseVertCoords &c, std::int64_t rSq)
void flip()
Definition MRInSphere.h:286
Vector3i64 pairV_
the fields are ordered by descending alignment to minimize the padding
Definition MRInSphere.h:266
Vector3i64 v
b - a, c - a
Definition MRInSphere.h:192
InSphereResult operator()(const PreciseVertCoords &d) const
Vector3i64 w
doubled normal of triangle abc, <= 2^63
Definition MRInSphere.h:193
InSphereResult operator()(const PreciseVertCoords &d) const
auto dot(const Matrix2< T > &a, const Matrix2< T > &b) -> decltype(dot(a.x, b.x))
double-dot product: x = a : b
Definition MRMatrix2.h:142
auto lengthSq() const -> decltype(std::declval< T >() *std::declval< T >())
Definition MRVector3.h:68
VertId vb_
Definition MRInSphere.h:268
bool outsideBothSpheres(const Vector3i &d) const
std::int64_t rSq
the squared radius of the sphere
Definition MRInSphere.h:197
Vector3i64 u
Definition MRInSphere.h:192
InSphereResult operator()(const Vector3i &d) const
bool reset(const PreciseVertCoords &a, const PreciseVertCoords &b, const PreciseVertCoords &c, std::int64_t rSq)
void flip()
Definition MRInSphere.h:179
bool reset(const Vector3< T > &va, const Vector3< T > &vb, const Vector3< T > &vc, T sqRadius)
Definition MRInSphere.h:84
std::array< FastInt< 192 >, 3 > M
2 * |w|^2 * ( circumcenter(abc) - a ), <= 2^161
Definition MRInSphere.h:195
MR_BIND_IGNORE const FastInt< 384 > & heightSq() const
Definition MRInSphere.h:262
InSphereResult operator()(const Vector3< T > &d) const
Definition MRInSphere.h:126
Vector3i pairPt_
the position of the coincident pair
Definition MRInSphere.h:267
void flip()
Definition MRInSphere.h:117
MR_BIND_TEMPLATE(std::pair< Vector3f, TriPointf > closestPointInTriangle(const Vector3f &p, const Vector3f &a, const Vector3f &b, const Vector3f &c))
std::array< Vector3f, 3 > MR_BIND_IGNORE
Definition MRMeshBuilderTypes.h:13
FastInt< 192 > W
|w|^2, <= 2^128
Definition MRInSphere.h:194
VertId vc_
the ids of the sphere points given in reset()
Definition MRInSphere.h:268
VertId va_
Definition MRInSphere.h:268
Vector3i a
the first sphere point
Definition MRInSphere.h:191
MR_BIND_IGNORE const FastInt< 192 > & normalSq() const
squared length of normal()
Definition MRInSphere.h:257
bool degenerateTriangle() const
Definition MRInSphere.h:244
void flip()
Definition MRInSphere.h:222
MR_BIND_IGNORE const Vector3i64 & normal() const
doubled normal cross( b - a, c - a ) of the triangle, directed at the sphere's center
Definition MRInSphere.h:254
int pairSigma_
the side of the limit sphere's center: +1 along ( -Vy, Vx, 0 ), -1 the opposite
Definition MRInSphere.h:269
FastInt< 384 > E
sqr( 2 * h * |w|^2 ), h = distance from plane abc to the sphere's center, <= 2^322
Definition MRInSphere.h:196
InSphereTester< int > InSphereTesteri
Definition MRInSphere.h:202
InSphereTester< double > InSphereTesterd
Definition MRInSphere.h:201
InSphereTester< float > InSphereTesterf
Definition MRInSphere.h:200
InSphereResult inSphere(const Vector3i &a, const Vector3i &b, const Vector3i &c, const Vector3i &d, std::int64_t rSq)
InSphereResult
the result of inSphere predicates
Definition MRInSphere.h:22
@ NoSphere
Definition MRInSphere.h:25
@ Outside
the sphere exists, and the point D is strictly outside
Definition MRInSphere.h:27
@ Inside
the sphere exists, and the point D is strictly inside
Definition MRInSphere.h:33
@ OnSphere
Definition MRInSphere.h:31
only for bindings generation
Definition MRCameraOrientationPlugin.h:8
Definition MRPrecisePredicates3.h:37
auto cross(const Vector2< T > &a, const Vector2< T > &b) -> decltype(a.x *b.x)
cross product
Definition MRVector2.h:160
Definition MRVector3.h:33