Graphics Reference
In-Depth Information
5.1.4.2 Closest Point on 3D Rectangle to Point
Determining the point
Q
on a 3D rectangle
R
closest to a given point
P
is virtually
equivalent to the problem of finding the closest point on an OBB, in that a 3D rectangle
can be seen as an OBB with zero extent along the
z
axis.
As such, a rectangle is defined by a center point
C
, two orthogonal unit vectors
u
0
and
u
1
specifying the orientation of the
x
and
y
axes of
R
, and two scalar values
e
0
and
e
1
specifying the rectangle halfwidth extents along each axis. In this representation,
all points
S
contained by
R
are given by
S
=
C
+
a
u
0
+
b
u
1
, where
|
a
| ≤
e
0
and
b
≤
e
1
. Expressed as code, this rectangle structure becomes:
struct Rect {
Point c;
// center point of rectangle
Vector u[2];
// unit vectors determining local x and y axes for the rectangle
float e[2];
// the halfwidth extents of the rectangle along the axes
};
Rewriting the
ClosestPtPointOBB()
code to account for a zero-extent
z
axis
results in the following code for finding the closest point on a 3D rectangle.
// Given point p, return point q on (or in) Rect r, closest to p
void ClosestPtPointRect(Point p, Rect r, Point &q)
{
Vectord=p-r.c;
// Start result at center of rect; make steps from there
q = r.c;
// For each rect axis...
for(inti=0;i<2;i++) {
// ...project d onto that axis to get the distance
// along the axis of d from the rect center
float dist = Dot(d, r.u[i]);
// If distance farther than the rect extents, clamp to the rect
if (dist > r.e[i]) dist = r.e[i];
if (dist < -r.e[i]) dist = -r.e[i];
// Step that distance along the axis to get world coordinate
q += dist * r.u[i];
}
}
A 3D rectangle
R
can also be given by three points (
A
,
B
, and
C
) such that the
vectors
B
−
−
A
and
C
A
span the rectangle. All points
S
in
R
are now given by