208 Chapter 6 Distance in 2D
if (t0 == 0 and t2 == 0) // closest point is vertex V0
return SquaredLength(Y - V0);
//Y=c0*V0+c1*V1+c2*V2forc0+c1+c2=1
GetBarycentricCoordinates(Y, V0, V1, V2, c0, c1, c2);
if (c0 < 0) // closest point is K1 on edge E1
return SquaredLength(Y - (V1 + t1 * (V2 - V1)));
if (c1 < 0) // closest point is K2 on edge E2
return SquaredLength(Y - (V2 + t2 * (V0 - V2)));
if (c2 < 0) // closest point is K0 on edge E0
return SquaredLength(Y - (V0 + t0 * (V1 - V0)));
return 0; // Y is inside triangle
}
The function ParameterOfClosestEdgePoint(P,E) effectively is what is used in
computing distance from a point to a line segment. The projection of P onto the
line containing the edge V
0
, V
1
is K =V
0
+t(V
1
−V
0
),wheret =(P −V
0
)/V
1
−
V
0
2
.Ift<0, it is clamped to t = 0 and the closest point to P is V
0
.Ift>1, it is
clamped to t =1 and the closest point is V
1
. Otherwise, t ∈[0, 1]and the closest point
is K. The aforementioned function returns the t value. If the function were to be
implemented as described, it involves a division by the squared length of the edge.
At least two calls are made to this function, so the distance calculator would require
a minimum of two divisions, an expensive proposition. A smarter implementation
does not do the division, but computes the numerator n and denominator d of t .If
n<0, t is clamped to 0. If n>d, t is clamped to 1. The numerators and denominators
should be stored as local variables at the scope of the function body for use later in the
barycentric coordinate calculations. If the function returns any of the three vertices,
the division n/d for any of the t-values is never performed.
The function
GetBarycentricCoordinates computes P =
2
i=0
c
i
V
i
,where
2
i=0
c
i
= 1. Once c
1
and c
2
are known, we can solve c
0
= 1 − c
1
− c
2
. The equa-
tion for P is equivalent to P − V
0
=c
1
(V
1
−V
0
) + c
2
(V
2
−V
0
). The vector equation
represents two linear equations in the two unknowns c
1
and c
2
, a system that can be
solved in the usual manner. The solution, if implemented in a straightforward man-
ner, requires a division by the determinant of the coefficient matrix. The division
is not necessary to perform. The barycentric calculator can return the coordinates
as three rational numbers c
i
= n
i
/d having the same denominator. The numerators
and denominator are returned in separate storage. The sign test c
0
< 0 is equivalent
to n
0
d<0, so the division is replaced by a multiplication. The conditional test is a
sign test, so the conventional floating-point comparison can be replaced by a (typi-
cally faster) test of the sign bit of the floating-point number. Even better would be to