25 template <
int N,
typename Real>
46 Real GetClampedRoot(Real slope, Real h0, Real h1);
52 void ComputeIntersection(Real
const sValue[2],
int const classify[2],
53 int edge[2], Real
end[2][2]);
57 void ComputeMinimumParameters(
int const edge[2], Real
const end[2][2],
61 Real mA, mB, mC, mD,
mE;
64 Real mF00, mF10, mF01,
mF11;
67 Real mG00, mG10, mG01,
mG11;
71 template <
int N,
typename Real>
74 template <
typename Real>
77 template <
typename Real>
81 template <
int N,
typename Real>
83 DCPQuery<Real, Segment<N, Real>, Segment<N, Real>>::operator()(
84 Segment<N, Real>
const& segment0, Segment<N, Real>
const& segment1)
86 return operator()(segment0.p[0], segment0.p[1], segment1.p[0],
90 template <
int N,
typename Real>
91 typename DCPQuery<Real, Segment<N, Real>, Segment<N, Real>>::Result
92 DCPQuery<Real, Segment<N, Real>, Segment<N, Real>>::operator()(
108 mA =
Dot(P1mP0, P1mP0);
109 mB =
Dot(P1mP0, Q1mQ0);
110 mC =
Dot(Q1mQ0, Q1mQ0);
111 mD =
Dot(P1mP0, P0mQ0);
112 mE =
Dot(Q1mQ0, P0mQ0);
124 if (mA > (Real)0 && mC > (Real)0)
134 sValue[0] = GetClampedRoot(mA, mF00, mF10);
135 sValue[1] = GetClampedRoot(mA, mF01, mF11);
138 for (
int i = 0; i < 2; ++i)
140 if (sValue[i] <= (Real)0)
144 else if (sValue[i] >= (Real)1)
154 if (classify[0] == -1 && classify[1] == -1)
157 result.parameter[0] = (Real)0;
158 result.parameter[1] = GetClampedRoot(mC, mG00, mG01);
160 else if (classify[0] == +1 && classify[1] == +1)
163 result.parameter[0] = (Real)1;
164 result.parameter[1] = GetClampedRoot(mC, mG10, mG11);
174 ComputeIntersection(sValue, classify, edge, end);
181 ComputeMinimumParameters(edge, end, result.parameter);
192 result.parameter[0] = GetClampedRoot(mA, mF00, mF10);
193 result.parameter[1] = (Real)0;
195 else if (mC > (Real)0)
201 result.parameter[0] = (Real)0;
202 result.parameter[1] = GetClampedRoot(mC, mG00, mG01);
207 result.parameter[0] = (Real)0;
208 result.parameter[1] = (Real)0;
214 ((Real)1 - result.parameter[0]) * P0 + result.parameter[0] * P1;
216 ((Real)1 - result.parameter[1]) * Q0 + result.parameter[1] * Q1;
218 result.sqrDistance =
Dot(diff, diff);
223 template <
int N,
typename Real>
224 Real DCPQuery<Real, Segment<N, Real>, Segment<N, Real>>::GetClampedRoot(
225 Real slope, Real h0, Real h1)
265 template <
int N,
typename Real>
266 void DCPQuery<Real, Segment<N, Real>, Segment<N, Real>>::ComputeIntersection(
267 Real
const sValue[2],
int const classify[2],
int edge[2], Real
end[2][2])
285 end[0][1] = mF00 / mB;
286 if (end[0][1] < (Real)0 || end[0][1] > (Real)1)
288 end[0][1] = (Real)0.5;
291 if (classify[1] == 0)
294 end[1][0] = sValue[1];
301 end[1][1] = mF10 / mB;
302 if (end[1][1] < (Real)0 || end[1][1] > (Real)1)
304 end[1][1] = (Real)0.5;
308 else if (classify[0] == 0)
311 end[0][0] = sValue[0];
318 end[1][1] = mF00 / mB;
319 if (end[1][1] < (Real)0 || end[1][1] > (Real)1)
321 end[1][1] = (Real)0.5;
324 else if (classify[1] == 0)
327 end[1][0] = sValue[1];
334 end[1][1] = mF10 / mB;
335 if (end[1][1] < (Real)0 || end[1][1] > (Real)1)
337 end[1][1] = (Real)0.5;
345 end[0][1] = mF10 / mB;
346 if (end[0][1] < (Real)0 || end[0][1] > (Real)1)
348 end[0][1] = (Real)0.5;
351 if (classify[1] == 0)
354 end[1][0] = sValue[1];
361 end[1][1] = mF00 / mB;
362 if (end[1][1] < (Real)0 || end[1][1] > (Real)1)
364 end[1][1] = (Real)0.5;
370 template <
int N,
typename Real>
371 void DCPQuery<Real, Segment<N, Real>, Segment<N, Real>>::
372 ComputeMinimumParameters(
int const edge[2], Real
const end[2][2],
375 Real delta = end[1][1] - end[0][1];
376 Real h0 = delta * (-mB * end[0][0] + mC * end[0][1] - mE);
381 parameter[0] = (Real)0;
382 parameter[1] = GetClampedRoot(mC, mG00, mG01);
384 else if (edge[0] == 1)
386 parameter[0] = (Real)1;
387 parameter[1] = GetClampedRoot(mC, mG10, mG11);
391 parameter[0] = end[0][0];
392 parameter[1] = end[0][1];
397 Real h1 = delta * (-mB * end[1][0] + mC * end[1][1] - mE);
402 parameter[0] = (Real)0;
403 parameter[1] = GetClampedRoot(mC, mG00, mG01);
405 else if (edge[1] == 1)
407 parameter[0] = (Real)1;
408 parameter[1] = GetClampedRoot(mC, mG10, mG11);
412 parameter[0] = end[1][0];
413 parameter[1] = end[1][1];
418 Real
z = std::min(std::max(h0 / (h0 - h1), (Real)0), (Real)1);
419 Real omz = (Real)1 - z;
420 parameter[0] = omz * end[0][0] + z * end[1][0];
421 parameter[1] = omz * end[0][1] + z * end[1][1];
GLsizei GLsizei GLfloat distance
static Real Sqrt(Real const &x)
Result operator()(Type0 const &primitive0, Type1 const &primitive1)
DualQuaternion< Real > Dot(DualQuaternion< Real > const &d0, DualQuaternion< Real > const &d1)
GLdouble GLdouble GLdouble z