Graphics Reference
In-Depth Information
computing
D
is not required. Because several subterms recur, the implementation
can be efficiently written as follows:
// Returns the squared distance between point c and segment ab
float SqDistPointSegment(Point a, Point b, Point c)
{
Vector ab=b-a,ac=c-a,bc=c-b;
float e = Dot(ac, ab);
// Handle cases where c projects outside ab
if (e <= 0.0f) return Dot(ac, ac);
float f = Dot(ab, ab);
if (e >= f) return Dot(bc, bc);
// Handle cases where c projects onto ab
return Dot(ac, ac)-e*e/f;
}
5.1.3
Closest Point on AABB to Point
Let
B
be an axis-aligned bounding box and
P
an arbitrary point in space. The point
Q
on
(or in)
B
closest to
P
is obtained by clamping
P
to the bounds of
B
on a componentwise
basis. There are four cases to consider for verifying that clamping gives the desired
result. If
P
is inside
B
, the clamped point is
P
itself, which is also the point in
B
closest to
P
.If
P
is in a face Voronoi region of
B
, the clamping operation will bring
P
to that face of
B
. (Voronoi regions were introduced in Chapter 3.) The clamping
corresponds to an orthogonal projection of
P
onto
B
and must therefore result in
the closest point on
B
. When
P
is in a vertex Voronoi region of
B
, clamping
P
gives
the vertex as a result, which again is the closest point on
B
. Finally, when
P
is in
an edge Voronoi region, clamping
P
corresponds to an orthogonal projection onto
the edge, which also must be the closest point on
B
to
P
. This procedure works in
both two and three dimensions. The clamping procedure for a 2D box is illustrated
in Figure 5.3, for the point
P
lying in an edge Voronoi region (a) and in a vertex
Voronoi region (b).
The following code implements the closest-point operation:
// Given point p, return the point q on or in AABB b that is closest to p
void ClosestPtPointAABB(Point p, AABB b, Point &q)
{
// For each coordinate axis, if the point coordinate value is
// outside box, clamp it to the box, else keep it as is