Graphics Reference
In-Depth Information
Similarly, given the point
S
1
(
s
)
=
P
1
+
s
d
1
on
S
1
, the closest point
L
2
(
t
)on
L
2
is
computed as
t
=
(
S
1
(
s
)
−
P
2
)
·
d
2
/
d
2
·
d
2
=
(
P
1
+
s
d
1
−
P
2
)
·
d
2
/
d
2
·
d
2
.
2 system of linear
equations to solve for the one unknown in terms of the other. In either case, the
expressions for
s
and
t
simplify to
Alternatively, Gaussian elimination can be used on the 2
×
s
=
(
bt
−
c
)/
a
t
=
(
bs
+
f
)/
e
,
with
a
=
d
1
·
d
1
,
b
=
d
1
·
d
2
,
c
=
d
1
·
r
,
e
=
d
2
·
d
2
, and
f
=
d
2
·
r
.
Code implementing this function follows.
// Clamp n to lie within the range [min, max]
float Clamp(float n, float min, float max) {
if (n < min) return min;
if (n > max) return max;
return n;
}
// Computes closest points C1 and C2 of S1(s)=P1+s*(Q1-P1) and
// S2(t)=P2+t*(Q2-P2), returning s and t. Function result is squared
// distance between between S1(s) and S2(t)
float ClosestPtSegmentSegment(Point p1, Point q1, Point p2, Point q2,
float &s, float &t, Point &c1, Point &c2)
{
Vector d1 = q1 - p1;
// Direction vector of segment S1
Vector d2 = q2 - p2;
// Direction vector of segment S2
Vectorr=p1-p2;
float a = Dot(d1, d1);
// Squared length of segment S1, always nonnegative
float e = Dot(d2, d2);
// Squared length of segment S2, always nonnegative
float f = Dot(d2, r);
// Check if either or both segments degenerate into points
if (a <= EPSILON && e <= EPSILON) {
// Both segments degenerate into points
s=t=0.0f;
c1 = p1;
c2 = p2;