Graphics Reference
In-Depth Information
D
D
D
B
B
B
P
A
C
P
C
A
A
C
(a)
(b)
(c)
Figure 5.10 (a) Segments AB and CD do not intersect because the intersection point P of
their extended lines lies outside the bounding box of CD . (b) Segments AB and CD intersect
because P lies inside the bounding boxes of both AB and CD . (c) Segment CD intersects the
line through AB because the triangles ABD and ABC have opposite winding.
of the extended line through the other segment. That is, for AB and CD to overlap, A
and B must be on different sides of CD and C and D must be on different sides of AB .
Testing whether the endpoints C and D are on different sides of AB can be done by
verifying that the triangles ABD and ABC wind in different directions (illustrated in
Figure 5.10c). To determine the winding, the signed triangle area can be computed.
Recall that the signed area is positive if the triangle winds counterclockwise, negative
if it winds clockwise, and zero if the triangle is degenerate (collinear or coincident
points).
// Returns 2 times the signed triangle area. The result is positive if
// abc is ccw, negative if abc is cw, zero if abc is degenerate.
float Signed2DTriArea(Point a, Point b, Point c)
{
return (a.x - c.x) * (b.y - c.y) - (a.y - c.y) * (b.x - c.x);
}
In the case in which the segments are intersecting, it turns out that the signed
areas computed to detect this can also be used to compute the intersection point. The
computation and its derivation are given in the following implementation.
// Test if segments ab and cd overlap. If they do, compute and return
// intersection t value along ab and intersection position p
int Test2DSegmentSegment(Point a, Point b, Point c, Point d, float &t, Point &p)
{
// Sign of areas correspond to which side of ab points c and d are
float a1 = Signed2DTriArea(a, b, d); // Compute winding of abd (+ or -)
float a2 = Signed2DTriArea(a, b, c); // To intersect, must have sign opposite of a1
 
Search WWH ::




Custom Search