mccaugh@s.cs.uiuc.edu (10/04/89)
> I need to find a formula/algorithm to determine if a line intersects > a polygon. I would perfer a method that would do this in as litte > time as possible. I need this for use in a forward raytracing > program. > CONST n = 20; (* e.g. *) TYPE line = RECORD a,b,c: Real END{line}; vertex = RECORD x,y: Real END{vertex}; side = RECORD A,B: vertex END{side}; index = 1..n; polygon = ARRAY[index] OF side; FUNCTION InSegment (VAR A,B,Q:vertex): Boolean; (* given that Q lies upon the line AB, *) (* determine if Q lies between A and B *) VAR p: Real; BEGIN IF A.x <> B.x THEN p := (Q.x - B.x)/(A.x - B.x) ELSE p := (Q.y - B.y)/(A.y - B.y); InSegment := (0.0<=p) AND (p<=1.0) END{InSegment}; FUNCTION Intersects: Boolean; (* see if line L intersects extended side *) VAR Q: vertex; (* point of intersection *) BEGIN (* if intersected, calls InSegment to see if point lies in side *) IF b1 = 0.0 THEN IF b2 = 0.0 THEN Intersects := a1*c2 = a2*c1 ELSE BEGIN WITH Q DO BEGIN x := c1/a1; y := (c2 - a2*c1/a1)/b2 END; Intersects := InSegment(A,B,Q) END ELSE IF b2 = 0.0 THEN BEGIN WITH Q DO BEGIN x := c2/a2; y := (c1 - a1*c2/a2)/b1 END; Intersects := InSegment(A,B,Q) END ELSE Intersects := b2*c1 = b1*c2 END{Intersects}; FUNCTION LineXPolygon (VAR L:line; VAR P:polygon): Boolean; (* returns TRUE if and only if line L intersects polygon P *) VAR s: index; (* index of current side of polygon P *) a1,b1,c1, (* coefficients of line L: normal form *) a2,b2,c2: Real; (* and of current side: " " *) BEGIN {LineXPolygon} WITH L DO BEGIN a1 := a; b1 := b; c1 := c END{WITH}; FOR s := 1 TO n DO BEGIN WITH P[s] DO BEGIN a2 := B.y - A.y; b2 := A.x - B.x; c2 := a2*B.x + b2*B.y END{WITH}; IF Intersects THEN BEGIN LineXPolygon := True; Exit END END{FOR}; LineXPolygon := False END{LineXPolygon};