Graphics Reference
In-Depth Information
void ClosestPtPointSegment(Point c, Point a, Point b, float &t, Point &d)
{
Vector ab=b-a;
// Project c onto ab, but deferring divide by Dot(ab, ab)
t = Dot(c - a, ab);
if (t <= 0.0f) {
// c projects outside the [a,b] interval, on the a side; clamp to a
t = 0.0f;
d=a;
} else {
float denom = Dot(ab, ab);
// Always nonnegative since denom = ||ab||
∧
2
if (t >= denom) {
// c projects outside the [a,b] interval, on the b side; clamp to b
t = 1.0f;
d=b;
} else {
// c projects inside the [a,b] interval; must do deferred divide now
t=t/denom;
d=a+t*ab;
}
}
}
The same basic method can be used for finding the closest point on a ray or the
closest point on a line. For a ray, it is necessary to clamp
t
only when it goes negative.
For a line, there is no need to clamp
t
at all.
5.1.2.1 Distance of Point to Segment
The squared distance between a point
C
and a segment
AB
can be directly computed
without explicitly computing the point
D
on
AB
closest to
C
. As in the preceding
section, there are three cases to consider. When
AC
·
AB
≤
0,
A
is closest to
C
and
the squared distance is given by
AC
·
AC
. When
AC
·
AB
≥
AB
·
AB
,
B
is closest to
C
and the squared distance is
BC
·
BC
. In the remaining case, 0
<
AC
·
AB
<
AB
·
AB
,
·
the squared distance is given by
CD
CD
, where
AC
·
AB
D
=
A
+
AB
AB
.
AB
·
However, because the expression
CD
·
CD
simplifies to
2
−
(
AC
·
AB
)
AC
·
AC
,
·
AB
AB