Skip to content

Instantly share code, notes, and snippets.

@lojikil
Created March 6, 2012 22:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lojikil/1989434 to your computer and use it in GitHub Desktop.
Save lojikil/1989434 to your computer and use it in GitHub Desktop.
procedure TClipper.IntersectEdges(e1,e2: PEdge;
const pt: TIntPoint; protects: TIntersectProtects = []);
procedure DoEdge1;
begin
AddOutPt(e1, e2, pt);
SwapSides(e1, e2);
SwapPolyIndexes(e1, e2);
end;
//----------------------------------------------------------------------
procedure DoEdge2;
begin
AddOutPt(e2, e1, pt);
SwapSides(e1, e2);
SwapPolyIndexes(e1, e2);
end;
//----------------------------------------------------------------------
procedure DoBothEdges;
begin
AddOutPt(e1, e2, pt);
AddOutPt(e2, e1, pt);
SwapSides(e1, e2);
SwapPolyIndexes(e1, e2);
end;
//----------------------------------------------------------------------
var
e1stops, e2stops: boolean;
e1Contributing, e2contributing: boolean;
e1FillType, e2FillType, e1FillType2, e2FillType2: TPolyFillType;
e1Wc, e2Wc, e1Wc2, e2Wc2: integer;
begin
{IntersectEdges}
//e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before
//e2 in AEL except when e1 is being inserted at the intersection point ...
e1stops := not (ipLeft in protects) and not assigned(e1.nextInLML) and
(e1.xtop = pt.x) and (e1.ytop = pt.y);
e2stops := not (ipRight in protects) and not assigned(e2.nextInLML) and
(e2.xtop = pt.x) and (e2.ytop = pt.y);
e1Contributing := (e1.outIdx >= 0);
e2contributing := (e2.outIdx >= 0);
//update winding counts...
//assumes that e1 will be to the right of e2 ABOVE the intersection
if e1.polyType = e2.polyType then
begin
if IsEvenOddFillType(e1) then
begin
e1Wc := e1.windCnt;
e1.windCnt := e2.windCnt;
e2.windCnt := e1Wc;
end else
begin
if e1.windCnt + e2.windDelta = 0 then
e1.windCnt := -e1.windCnt else
inc(e1.windCnt, e2.windDelta);
if e2.windCnt - e1.windDelta = 0 then
e2.windCnt := -e2.windCnt else
dec(e2.windCnt, e1.windDelta);
end;
end else
begin
if not IsEvenOddFillType(e2) then inc(e1.windCnt2, e2.windDelta)
else if e1.windCnt2 = 0 then e1.windCnt2 := 1
else e1.windCnt2 := 0;
if not IsEvenOddFillType(e1) then dec(e2.windCnt2, e1.windDelta)
else if e2.windCnt2 = 0 then e2.windCnt2 := 1
else e2.windCnt2 := 0;
end;
if e1.polyType = ptSubject then
begin
e1FillType := fSubjFillType;
e1FillType2 := fClipFillType;
end else
begin
e1FillType := fClipFillType;
e1FillType2 := fSubjFillType;
end;
if e2.polyType = ptSubject then
begin
e2FillType := fSubjFillType;
e2FillType2 := fClipFillType;
end else
begin
e2FillType := fClipFillType;
e2FillType2 := fSubjFillType;
end;
case e1FillType of
pftPositive: e1Wc := e1.windCnt;
pftNegative : e1Wc := -e1.windCnt;
else e1Wc := abs(e1.windCnt);
end;
case e2FillType of
pftPositive: e2Wc := e2.windCnt;
pftNegative : e2Wc := -e2.windCnt;
else e2Wc := abs(e2.windCnt);
end;
if e1Contributing and e2contributing then
begin
if e1stops or e2stops or not (e1Wc in [0,1]) or not (e2Wc in [0,1]) or
((e1.polytype <> e2.polytype) and (fClipType <> ctXor)) then
AddLocalMaxPoly(e1, e2, pt) else
DoBothEdges;
end else if e1Contributing then
begin
if ((e2Wc = 0) or (e2Wc = 1)) and
((fClipType <> ctIntersection) or (e2.polyType = ptSubject) or
(e2.windCnt2 <> 0)) then DoEdge1;
end
else if e2contributing then
begin
if ((e1Wc = 0) or (e1Wc = 1)) and
((fClipType <> ctIntersection) or (e1.polyType = ptSubject) or
(e1.windCnt2 <> 0)) then DoEdge2;
end
else if ((e1Wc = 0) or (e1Wc = 1)) and ((e2Wc = 0) or (e2Wc = 1)) and
not e1stops and not e2stops then
begin
//neither edge is currently contributing ...
case e1FillType2 of
pftPositive: e1Wc2 := e1.windCnt2;
pftNegative : e1Wc2 := -e1.windCnt2;
else e1Wc2 := abs(e1.windCnt2);
end;
case e2FillType2 of
pftPositive: e2Wc2 := e2.windCnt2;
pftNegative : e2Wc2 := -e2.windCnt2;
else e2Wc2 := abs(e2.windCnt2);
end;
if (e1.polytype <> e2.polytype) then
AddLocalMinPoly(e1, e2, pt)
else if (e1Wc = 1) and (e2Wc = 1) then
case fClipType of
ctIntersection:
if (e1Wc2 > 0) and (e2Wc2 > 0) then
AddLocalMinPoly(e1, e2, pt);
ctUnion:
if (e1Wc2 <= 0) and (e2Wc2 <= 0) then
AddLocalMinPoly(e1, e2, pt);
ctDifference:
if ((e1.polyType = ptClip) and (e1Wc2 > 0) and (e2Wc2 > 0)) or
((e1.polyType = ptSubject) and (e1Wc2 <= 0) and (e2Wc2 <= 0)) then
AddLocalMinPoly(e1, e2, pt);
ctXor:
AddLocalMinPoly(e1, e2, pt);
end
else
swapsides(e1,e2);
end;
if (e1stops <> e2stops) and
((e1stops and (e1.outIdx >= 0)) or (e2stops and (e2.outIdx >= 0))) then
begin
swapsides(e1,e2);
SwapPolyIndexes(e1, e2);
end;
//finally, delete any non-contributing maxima edges ...
if e1stops then deleteFromAEL(e1);
if e2stops then deleteFromAEL(e2);
end;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment