25 template <
typename Real>
65 bool operator< (ClosestInfo
const& info)
const 67 return sqrDistance < info.sqrDistance;
78 Real Bisect(Real m2b2, Real rm0sqr, Real m0sqr, Real b1sqr,
79 Real smin, Real smax);
83 template <
typename Real>
90 Real
const zero = (Real)0;
101 Real NdM =
Dot(circle.normal, line.direction);
106 Real
a =
Dot(NxM, NxM),
b =
Dot(NxM, NxD);
107 Real
c =
Dot(NxD, NxD), d =
Dot(line.direction, D);
108 Real rsqr = circle.radius * circle.radius;
109 Real asqr = a *
a, bsqr =
b *
b, dsqr = d * d;
110 Real h0 = c * dsqr - bsqr * rsqr;
111 Real h1 = 2 * (c * d + b * dsqr - a * b * rsqr);
112 Real h2 = c + 4 * b * d + a * dsqr - asqr * rsqr;
113 Real h3 = 2 * (b + a * d);
116 std::map<Real, int> rmMap;
118 h0, h1, h2, h3, h4, rmMap);
119 std::array<ClosestInfo, 4> candidates;
121 for (
auto const& rm : rmMap)
126 if (NxDelta != vzero)
128 GetPair(line, circle, D,t, info.lineClosest,
130 info.equidistant =
false;
135 info.lineClosest = circle.center;
137 circle.center + circle.radius * U;
138 info.equidistant =
true;
141 info.sqrDistance =
Dot(diff, diff);
142 candidates[numRoots++] = info;
145 std::sort(candidates.begin(), candidates.begin() + numRoots);
147 result.numClosestPairs = 1;
148 result.lineClosest[0] = candidates[0].lineClosest;
149 result.circleClosest[0] = candidates[0].circleClosest;
151 && candidates[1].sqrDistance == candidates[0].sqrDistance)
153 result.numClosestPairs = 2;
154 result.lineClosest[1] = candidates[1].lineClosest;
155 result.circleClosest[1] = candidates[1].circleClosest;
162 Real u =
Dot(NxM, D),
v =
Dot(line.direction, D);
163 Real discr = circle.radius * circle.radius - u * u;
166 result.numClosestPairs = 2;
169 GetPair(line, circle, D, t, result.lineClosest[0],
170 result.circleClosest[0]);
172 GetPair(line, circle, D, t, result.lineClosest[1],
173 result.circleClosest[1]);
177 result.numClosestPairs = 1;
179 GetPair(line, circle, D, t, result.lineClosest[0],
180 result.circleClosest[0]);
190 result.numClosestPairs = 2;
191 t = circle.radius *
Length(NxM);
192 GetPair(line, circle, D, t, result.lineClosest[0],
193 result.circleClosest[0]);
195 GetPair(line, circle, D, t, result.lineClosest[1],
196 result.circleClosest[1]);
198 result.equidistant =
false;
206 result.numClosestPairs = 1;
207 t = -
Dot(line.direction, D);
208 GetPair(line, circle, D, t, result.lineClosest[0],
209 result.circleClosest[0]);
210 result.equidistant =
false;
217 result.numClosestPairs = 1;
218 result.lineClosest[0] = circle.center;
219 result.circleClosest[0] = circle.center + circle.radius * U;
220 result.equidistant =
true;
224 Vector3<Real> diff = result.lineClosest[0] - result.circleClosest[0];
225 result.sqrDistance =
Dot(diff, diff);
230 template <
typename Real>
238 Real
const zero = (Real)0;
244 Real m0sqr =
Dot(MxN, MxN);
251 std::array<Real, 3> roots;
257 Real rm0 = circle.
radius * m0;
258 Real lambda = -
Dot(MxN, DxN) / m0sqr;
263 Real b1sqr =
Dot(DxN, DxN);
269 Real rm0sqr = circle.
radius * m0sqr;
272 Real
const twoThirds = (Real)2 / (Real)3;
274 rm0sqr * b1sqr, twoThirds) - b1sqr) / m0;
276 m0sqr * sHat * sHat + b1sqr);
277 Real cutoff = gHat - sHat;
280 s = Bisect(m2b2, rm0sqr, m0sqr, b1sqr, -m2b2,
282 roots[numRoots++] =
s;
285 roots[numRoots++] = -sHat;
288 else if (m2b2 >= cutoff)
290 s = Bisect(m2b2, rm0sqr, m0sqr, b1sqr, -m2b2 - rm0,
292 roots[numRoots++] =
s;
295 roots[numRoots++] = sHat;
302 s = Bisect(m2b2, rm0sqr, m0sqr, b1sqr, -m2b2,
304 roots[numRoots++] =
s;
305 s = Bisect(m2b2, rm0sqr, m0sqr, b1sqr, -m2b2 - rm0,
307 roots[numRoots++] =
s;
311 s = Bisect(m2b2, rm0sqr, m0sqr, b1sqr, -m2b2 - rm0,
313 roots[numRoots++] =
s;
314 s = Bisect(m2b2, rm0sqr, m0sqr, b1sqr, sHat,
316 roots[numRoots++] =
s;
324 s = Bisect(m2b2, rm0sqr, m0sqr, b1sqr, -m2b2,
327 else if (m2b2 > zero)
329 s = Bisect(m2b2, rm0sqr, m0sqr, b1sqr, -m2b2 - rm0,
336 roots[numRoots++] =
s;
345 roots[numRoots++] =
s;
347 else if (m2b2 > zero)
350 roots[numRoots++] =
s;
355 roots[numRoots++] =
s;
357 roots[numRoots++] =
s;
361 std::array<ClosestInfo, 4> candidates;
362 for (
int i = 0; i < numRoots; ++i)
364 t = roots[i] + lambda;
368 if (NxDelta != vzero)
370 GetPair(line, circle, oldD, t, info.lineClosest,
372 info.equidistant =
false;
377 info.lineClosest = circle.
center;
379 info.equidistant =
true;
382 info.sqrDistance =
Dot(diff, diff);
383 candidates[i] = info;
386 std::sort(candidates.begin(), candidates.begin() + numRoots);
388 result.numClosestPairs = 1;
389 result.lineClosest[0] = candidates[0].lineClosest;
390 result.circleClosest[0] = candidates[0].circleClosest;
392 && candidates[1].sqrDistance == candidates[0].sqrDistance)
394 result.numClosestPairs = 2;
395 result.lineClosest[1] = candidates[1].lineClosest;
396 result.circleClosest[1] = candidates[1].circleClosest;
399 result.equidistant =
false;
407 result.numClosestPairs = 1;
409 result.lineClosest[0], result.circleClosest[0]);
410 result.equidistant =
false;
417 result.numClosestPairs = 1;
418 result.lineClosest[0] = circle.
center;
419 result.circleClosest[0] = circle.
center + circle.
radius * U;
420 result.equidistant =
true;
424 Vector3<Real> diff = result.lineClosest[0] - result.circleClosest[0];
425 result.sqrDistance =
Dot(diff, diff);
430 template <
typename Real>
437 lineClosest = circle.
center + delta;
443 template <
typename Real>
445 Real rm0sqr, Real m0sqr, Real b1sqr, Real smin, Real smax)
447 std::function<Real(Real)> G = [&, m2b2, rm0sqr, m0sqr, b1sqr](Real
s)
460 maxIterations, root);
static unsigned int GetMaxBisections()
GLsizei GLsizei GLfloat distance
static Real Sqrt(Real const &x)
Vector3< Real > lineClosest
Vector< N, Real > direction
GLboolean GLboolean GLboolean GLboolean a
Vector< N, Real > GetOrthogonal(Vector< N, Real > const &v, bool unitLength)
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
Real Normalize(GVector< Real > &v, bool robust=false)
DualQuaternion< Real > Cross(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLboolean GLboolean GLboolean b
DualQuaternion< Real > Length(DualQuaternion< Real > const &d, bool robust=false)
static unsigned int Find(std::function< Real(Real)> const &F, Real t0, Real t1, unsigned int maxIterations, Real &root)