22 template <
typename Real>
31 ELLIPSOID1_CONTAINS_ELLIPSOID0
48 void GetRoots(Real d0, Real c0,
int& numRoots, Real* roots);
49 void GetRoots(Real d0, Real d1, Real c0, Real c1,
int& numRoots,
51 void GetRoots(Real d0, Real d1, Real d2, Real c0, Real c1, Real c2,
52 int& numRoots, Real* roots);
56 template <
typename Real>
63 Real
const zero = (Real)0;
64 Real
const one = (Real)1;
69 R0.
SetCol(0, ellipsoid0.axis[0]);
70 R0.
SetCol(1, ellipsoid0.axis[1]);
71 R0.
SetCol(2, ellipsoid0.axis[2]);
73 one / (ellipsoid0.extent[0] * ellipsoid0.extent[0]),
74 one / (ellipsoid0.extent[1] * ellipsoid0.extent[1]),
75 one / (ellipsoid0.extent[2] * ellipsoid0.extent[2]) };
80 R1.
SetCol(0, ellipsoid1.axis[0]);
81 R1.
SetCol(1, ellipsoid1.axis[1]);
82 R1.
SetCol(2, ellipsoid1.axis[2]);
84 one / (ellipsoid1.extent[0] * ellipsoid1.extent[0]),
85 one / (ellipsoid1.extent[1] * ellipsoid1.extent[1]),
86 one / (ellipsoid1.extent[2] * ellipsoid1.extent[2]) };
92 ellipsoid0.extent[2] };
94 one / ellipsoid0.extent[0],
95 one / ellipsoid0.extent[1],
96 one / ellipsoid0.extent[2] };
105 std::array<Real, 3> D;
106 std::array<std::array<Real, 3>, 3> evec;
107 es(M2(0, 0), M2(0, 1), M2(0, 2), M2(1, 1), M2(1, 2), M2(2, 2),
false, +1,
123 Real minSqrDistance = std::numeric_limits<Real>::max();
124 Real maxSqrDistance = zero;
131 for (i = 0; i < 3; ++i)
133 Real invD = one / D[i];
134 if (invD < minSqrDistance)
136 minSqrDistance = invD;
138 if (invD > maxSqrDistance)
140 maxSqrDistance = invD;
144 if (maxSqrDistance < one)
146 result.relationship = ELLIPSOID0_CONTAINS_ELLIPSOID1;
148 else if (minSqrDistance >(Real)1)
150 result.relationship = ELLIPSOID1_CONTAINS_ELLIPSOID0;
154 result.relationship = ELLIPSOIDS_INTERSECTING;
156 result.intersect =
true;
165 Real d0 = D[0], d1 = D[1], d2 = D[2];
166 Real c0 = K[0] * K[0], c1 = K[1] * K[1], c2 = K[2] * K[2];
170 std::vector<std::pair<Real, Real>>
param(3);
171 param[0] = std::make_pair(d0, c0);
172 param[1] = std::make_pair(d1, c1);
173 param[2] = std::make_pair(d2, c2);
174 std::sort(param.begin(), param.end(),
175 std::greater<std::pair<Real, Real>>());
177 std::vector<std::pair<Real, Real>> valid;
181 if (param[1].first > param[2].first)
184 for (i = 0; i < 3; ++i)
186 if (param[i].second >(Real)0)
188 valid.push_back(param[i]);
195 if (param[0].second > (Real)0)
197 valid.push_back(param[0]);
199 param[1].second += param[0].second;
200 if (param[1].second > (Real)0)
202 valid.push_back(param[1]);
208 if (param[1].first > param[2].first)
211 param[0].second += param[1].second;
212 if (param[0].second > (Real)0)
214 valid.push_back(param[0]);
216 if (param[2].second > (Real)0)
218 valid.push_back(param[2]);
224 param[0].second += param[1].second + param[2].second;
225 if (param[0].second > (Real)0)
227 valid.push_back(param[0]);
232 size_t numValid = valid.size();
237 GetRoots(valid[0].first, valid[1].first, valid[2].first,
238 valid[0].second, valid[1].second, valid[2].second, numRoots,
241 else if (numValid == 2)
243 GetRoots(valid[0].first, valid[1].first, valid[0].second,
244 valid[1].second, numRoots, roots);
246 else if (numValid == 1)
248 GetRoots(valid[0].first, valid[0].second, numRoots, roots);
254 result.intersect =
true;
255 result.relationship = ELLIPSOIDS_INTERSECTING;
259 for (i = 0; i < numRoots; ++i)
262 Real p0 = d0*K[0] * s / (d0 * s - (Real)1);
263 Real p1 = d1*K[1] * s / (d1 * s - (Real)1);
264 Real p2 = d2*K[2] * s / (d2 * s - (Real)1);
265 Real sqrDistance = p0 * p0 + p1 * p1 + p2 * p2;
266 if (sqrDistance < minSqrDistance)
268 minSqrDistance = sqrDistance;
270 if (sqrDistance > maxSqrDistance)
272 maxSqrDistance = sqrDistance;
276 if (maxSqrDistance < one)
278 result.intersect =
true;
279 result.relationship = ELLIPSOID0_CONTAINS_ELLIPSOID1;
281 else if (minSqrDistance >(Real)1)
283 if (d0 * c0 + d1 * c1 + d2 * c2 > one)
285 result.intersect =
false;
286 result.relationship = ELLIPSOIDS_SEPARATED;
290 result.intersect =
true;
291 result.relationship = ELLIPSOID1_CONTAINS_ELLIPSOID0;
296 result.intersect =
true;
297 result.relationship = ELLIPSOIDS_INTERSECTING;
303 template <
typename Real>
305 Real c0,
int& numRoots, Real* roots)
308 Real
const one = (Real)1;
309 Real temp = sqrt(d0*c0);
312 roots[0] = (one - temp) * inv;
313 roots[1] = (one + temp) * inv;
316 template <
typename Real>
318 Real d1, Real c0, Real c1,
int& numRoots, Real* roots)
323 Real
const zero = (Real)0;
324 Real
const one = (Real)1;
325 Real
const two = (Real)2;
329 std::function<Real(Real)> F = [&one, d0, d1, d0c0, d1c1](Real
s)
331 Real invN0 = one / (d0*
s - one);
332 Real invN1 = one / (d1*
s - one);
333 Real term0 = d0c0 * invN0 * invN0;
334 Real term1 = d1c1 * invN1 * invN1;
335 Real
f = term0 + term1 - one;
339 std::function<Real(Real)> DF = [&one, &two, d0, d1, d0c0, d1c1](Real
s)
341 Real invN0 = one / (d0*
s - one);
342 Real invN1 = one / (d1*
s - one);
343 Real term0 = d0 * d0c0 * invN0 * invN0 * invN0;
344 Real term1 = d1 * d1c1 * invN1 * invN1 * invN1;
345 Real df = -two * (term0 + term1);
349 unsigned int const maxIterations = 1024;
350 unsigned int iterations;
354 Real
const epsilon = (Real)0.001;
355 Real multiplier0 = sqrt(two / (one - epsilon));
356 Real multiplier1 = sqrt(one / (one + epsilon));
357 Real sqrtd0c0 = sqrt(d0c0);
358 Real sqrtd1c1 = sqrt(d1c1);
359 Real invD0 = one / d0;
360 Real invD1 = one / d1;
361 Real temp0, temp1, smin, smax,
s;
364 temp0 = (one - multiplier0 * sqrtd0c0) * invD0;
365 temp1 = (one - multiplier0 * sqrtd1c1) * invD1;
366 smin = std::min(temp0, temp1);
367 LogAssert(F(smin) < zero,
"Unexpected condition.");
368 smax = (one - multiplier1*sqrtd0c0)*invD0;
369 LogAssert(F(smax) > zero,
"Unexpected condition.");
371 LogAssert(iterations > 0,
"Unexpected condition.");
372 roots[numRoots++] =
s;
384 maxIterations, smid);
385 LogAssert(iterations > 0,
"Unexpected condition.");
392 LogAssert(iterations > 0,
"Unexpected condition.");
393 roots[numRoots++] =
s;
396 LogAssert(iterations > 0,
"Unexpected condition.");
397 roots[numRoots++] =
s;
401 temp0 = (one + multiplier0 * sqrtd0c0) * invD0;
402 temp1 = (one + multiplier0 * sqrtd1c1) * invD1;
403 smax = std::max(temp0, temp1);
404 LogAssert(F(smax) < zero,
"Unexpected condition.");
405 smin = (one + multiplier1 * sqrtd1c1) * invD1;
406 LogAssert(F(smin) > zero,
"Unexpected condition.");
408 LogAssert(iterations > 0,
"Unexpected condition.");
409 roots[numRoots++] =
s;
412 template <
typename Real>
414 Real d1, Real d2, Real c0, Real c1, Real c2,
int& numRoots, Real* roots)
419 Real
const zero = (Real)0;
420 Real
const one = (Real)1;
421 Real
const three = (Real)3;
426 std::function<Real(Real)> F = [&one, d0, d1, d2, d0c0, d1c1, d2c2](Real
s)
428 Real invN0 = one / (d0*
s - one);
429 Real invN1 = one / (d1*
s - one);
430 Real invN2 = one / (d2*
s - one);
431 Real term0 = d0c0 * invN0 * invN0;
432 Real term1 = d1c1 * invN1 * invN1;
433 Real term2 = d2c2 * invN2 * invN2;
434 Real
f = term0 + term1 + term2 - one;
438 std::function<Real(Real)> DF = [&one, d0, d1, d2, d0c0, d1c1, d2c2](Real
s)
440 Real
const two = (Real)2;
441 Real invN0 = one / (d0*
s - one);
442 Real invN1 = one / (d1*
s - one);
443 Real invN2 = one / (d2*
s - one);
444 Real term0 = d0 * d0c0 * invN0 * invN0 * invN0;
445 Real term1 = d1 * d1c1 * invN1 * invN1 * invN1;
446 Real term2 = d2 * d2c2 * invN2 * invN2 * invN2;
447 Real df = -two * (term0 + term1 + term2);
451 unsigned int const maxIterations = 1024;
452 unsigned int iterations;
456 Real epsilon = (Real)0.001;
457 Real multiplier0 = sqrt(three / (one - epsilon));
458 Real multiplier1 = sqrt(one / (one + epsilon));
459 Real sqrtd0c0 = sqrt(d0c0);
460 Real sqrtd1c1 = sqrt(d1c1);
461 Real sqrtd2c2 = sqrt(d2c2);
462 Real invD0 = one / d0;
463 Real invD1 = one / d1;
464 Real invD2 = one / d2;
465 Real temp0, temp1, temp2, smin, smax,
s;
468 temp0 = (one - multiplier0*sqrtd0c0)*invD0;
469 temp1 = (one - multiplier0*sqrtd1c1)*invD1;
470 temp2 = (one - multiplier0*sqrtd2c2)*invD2;
471 smin = std::min(std::min(temp0, temp1), temp2);
472 LogAssert(F(smin) < zero,
"Unexpected condition.");
473 smax = (one - multiplier1*sqrtd0c0)*invD0;
474 LogAssert(F(smax) > zero,
"Unexpected condition.");
476 LogAssert(iterations > 0,
"Unexpected condition.");
477 roots[numRoots++] =
s;
489 maxIterations, smid);
490 LogAssert(iterations > 0,
"Unexpected condition.");
497 LogAssert(iterations > 0,
"Unexpected condition.");
498 roots[numRoots++] =
s;
501 LogAssert(iterations > 0,
"Unexpected condition.");
502 roots[numRoots++] =
s;
514 maxIterations, smid);
515 LogAssert(iterations > 0,
"Unexpected condition.");
522 LogAssert(iterations > 0,
"Unexpected condition.");
523 roots[numRoots++] =
s;
526 LogAssert(iterations > 0,
"Unexpected condition.");
527 roots[numRoots++] =
s;
531 temp0 = (one + multiplier0*sqrtd0c0)*invD0;
532 temp1 = (one + multiplier0*sqrtd1c1)*invD1;
533 temp2 = (one + multiplier0*sqrtd2c2)*invD2;
534 smax = std::max(std::max(temp0, temp1), temp2);
535 LogAssert(F(smax) < zero,
"Unexpected condition.");
536 smin = (one + multiplier1*sqrtd2c2)*invD2;
537 LogAssert(F(smin) > zero,
"Unexpected condition.");
539 LogAssert(iterations > 0,
"Unexpected condition.");
540 roots[numRoots++] =
s;
#define LogAssert(condition, message)
GMatrix< Real > MultiplyATB(GMatrix< Real > const &A, GMatrix< Real > const &B)
#define LogError(message)
void SetCol(int c, Vector< NumRows, Real > const &vec)
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
static unsigned int Find(std::function< Real(Real)> const &F, Real t0, Real t1, unsigned int maxIterations, Real &root)