7 #ifndef __geometry_BoundingSphere_h__ 8 #define __geometry_BoundingSphere_h__ 10 #define FE_BOS_DEBUG FALSE 12 #define FE_BOS_MULTIPLICITIVE FALSE 19 const Real boundEpsilon=1e-3;
20 #if FE_BOS_MULTIPLICITIVE 21 const Real boundFactor=1.001;
37 static void solve(
const Vector<3,T>* a_pEnclosed,U32 a_enclosedCount,
57 static void solveRecursive(
const Vector<3,T>** a_ppPoints,
58 U32 a_enclosedCount,U32 a_boundaryCount,
69 for(U32 i=0;i<a_enclosedCount;i++)
70 ppPoints[i]=&a_pEnclosed[i];
72 solveRecursive(ppPoints,a_enclosedCount,0,a_rCenter,a_rRadius);
80 U32 a_enclosedCount,U32 a_boundaryCount,
91 feLog(
"solveRecursive %p %d %d\n",
92 a_ppPoints,a_enclosedCount,a_boundaryCount);
93 for(I32 m= -a_boundaryCount;m<0;m++)
95 feLog(
" b %d %p (%s)\n",m,a_ppPoints[m],c_print(*a_ppPoints[m]));
97 for(U32 m=0;m<a_enclosedCount;m++)
99 feLog(
" e %d %p (%s)\n",m,a_ppPoints[m],c_print(*a_ppPoints[m]));
104 a_rCenter,a_rRadius);
105 if(a_boundaryCount==4)
110 #if FE_BOS_MULTIPLICITIVE 111 T radiusPlus=fe::maximum(a_rRadius+boundEpsilon,a_rRadius*boundFactor);
113 T radiusPlus=a_rRadius+boundEpsilon;
116 T r2=radiusPlus*radiusPlus;
118 for(U32 i=0;i<a_enclosedCount;i++)
121 feLog(
"check %d %p (%s)\n",
122 i,a_ppPoints[i],c_print(*a_ppPoints[i]));
124 if(magnitudeSquared(*a_ppPoints[i]-a_rCenter)>r2)
127 feLog(
"fit (%s) - (%s) %.6G vs %.6G\n",
128 c_print(*a_ppPoints[i]),c_print(a_rCenter),
129 magnitudeSquared(*a_ppPoints[i]-a_rCenter),r2);
134 feLog(
"sort %d/%d %p %p (%s) (%s)\n",
135 j,i,a_ppPoints[j-1],a_ppPoints[j],
136 c_print(*a_ppPoints[j-1]),
137 c_print(*a_ppPoints[j]));
140 a_ppPoints[j]=a_ppPoints[j-1];
141 a_ppPoints[j-1]=point;
145 solveRecursive(a_ppPoints+1,i,a_boundaryCount+1,
146 a_rCenter,a_rRadius);
148 #if FE_BOS_MULTIPLICITIVE 149 radiusPlus=fe::maximum(a_rRadius+boundEpsilon,
150 a_rRadius*boundFactor);
152 radiusPlus=a_rRadius+boundEpsilon;
155 r2=radiusPlus*radiusPlus;
160 template <
typename T>
162 const Vector<3,T>** a_ppBoundary, U32 a_boundaryCount,
165 #if FE_BOS_MULTIPLICITIVE 166 const Real threshold=fe::maximum(boundEpsilon,
167 a_rRadius*(Real(1)-boundFactor));
169 const Real threshold=boundEpsilon;
172 for(U32 m=0;m<a_boundaryCount;m++)
174 for(U32 n=m+1;n<a_boundaryCount;n++)
176 if(magnitudeSquared(*a_ppBoundary[n]-*a_ppBoundary[m])<threshold)
178 if(n<a_boundaryCount-1)
181 a_ppBoundary[n]=a_ppBoundary[a_boundaryCount-1];
182 a_ppBoundary[a_boundaryCount-1]=point;
188 solveBoundary(a_ppBoundary,a_boundaryCount,a_rCenter,a_rRadius);
191 template <
typename T>
193 const Vector<3,T>** a_ppBoundary, U32 a_boundaryCount,
197 feLog(
"solveBoundary %p %d\n",a_ppBoundary,a_boundaryCount);
198 for(U32 m=0;m<a_boundaryCount;m++)
200 feLog(
" %d %p (%s)\n",m,a_ppBoundary[m],c_print(*a_ppBoundary[m]));
203 switch(a_boundaryCount)
207 const Vector<3,T> edge1=*a_ppBoundary[1]-*a_ppBoundary[0];
208 const Vector<3,T> edge2=*a_ppBoundary[2]-*a_ppBoundary[0];
209 const Vector<3,T> edge3=*a_ppBoundary[3]-*a_ppBoundary[0];
210 const T denom=T(2)*determinant3x3(
211 edge1[0],edge1[1],edge1[2],
212 edge2[0],edge2[1],edge2[2],
213 edge3[0],edge3[1],edge3[2]);
216 const Vector<3,T> to=(dot(edge3,edge3)*cross(edge1,edge2)+
217 dot(edge2,edge2)*cross(edge3,edge1)+
218 dot(edge1,edge1)*cross(edge2,edge3))/denom;
220 #if FE_BOS_MULTIPLICITIVE 221 a_rRadius=fe::maximum(magnitude(to)+boundEpsilon,
222 magnitude(to)*boundFactor);
224 a_rRadius=magnitude(to)+boundEpsilon;
227 a_rCenter=*a_ppBoundary[0]+to;
231 #if FE_CPLUSPLUS >= 201703L 237 const Vector<3,T> edge1=*a_ppBoundary[1]-*a_ppBoundary[0];
238 const Vector<3,T> edge2=*a_ppBoundary[2]-*a_ppBoundary[0];
240 const T denom=T(2)*dot(perp,perp);
243 const Vector<3,T> to=(dot(edge2,edge2)*cross(perp,edge1)+
244 dot(edge1,edge1)*cross(edge2,perp))/denom;
246 #if FE_BOS_MULTIPLICITIVE 247 a_rRadius=fe::maximum(magnitude(to)+boundEpsilon,
248 magnitude(to)*boundFactor);
250 a_rRadius=magnitude(to)+boundEpsilon;
253 a_rCenter=*a_ppBoundary[0]+to;
257 #if FE_CPLUSPLUS >= 201703L 263 Vector<3,T> diff=*a_ppBoundary[1]-*a_ppBoundary[0];
266 #if FE_BOS_MULTIPLICITIVE 267 a_rRadius=fe::maximum(magnitude(half)+boundEpsilon,
268 magnitude(half)*boundFactor);
270 a_rRadius=magnitude(half)+boundEpsilon;
273 a_rCenter=*a_ppBoundary[0]+half;
277 a_rCenter=*a_ppBoundary[0];
286 feLog(
" center (%s) radius %.6G\n",c_print(a_rCenter),a_rRadius);
kernel
Definition: namespace.dox:3
static void solveBoundary(const Vector< 3, T > **a_ppBoundary, U32 a_boundaryCount, Vector< 3, T > &a_rCenter, T &a_rRadius)
create a sphere containing 0 to 4 points
Definition: BoundingSphere.h:192
static void solveBoundarySafe(const Vector< 3, T > **a_ppBoundary, U32 a_boundaryCount, Vector< 3, T > &a_rCenter, T &a_rRadius)
create a sphere containing 0 to 4 points
Definition: BoundingSphere.h:161
Bounding sphere for arbitrary points.
Definition: BoundingSphere.h:34