Created
March 6, 2012 22:27
-
-
Save lojikil/1989434 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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