update clipper to 7.3 release
This commit is contained in:
parent
cbea4335f4
commit
0544854dc9
2 changed files with 66 additions and 48 deletions
|
@ -1,8 +1,8 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* *
|
* *
|
||||||
* Author : Angus Johnson *
|
* Author : Angus Johnson *
|
||||||
* Version : 4.6.5 *
|
* Version : 4.7.3 *
|
||||||
* Date : 17 January 2011 *
|
* Date : 7 March 2012 *
|
||||||
* Website : http://www.angusj.com *
|
* Website : http://www.angusj.com *
|
||||||
* Copyright : Angus Johnson 2010-2012 *
|
* Copyright : Angus Johnson 2010-2012 *
|
||||||
* *
|
* *
|
||||||
|
@ -352,8 +352,15 @@ bool Orientation(const Polygon &poly)
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline bool PointsEqual( const IntPoint &pt1, const IntPoint &pt2)
|
||||||
|
{
|
||||||
|
return ( pt1.X == pt2.X && pt1.Y == pt2.Y );
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
bool Orientation(OutRec *outRec, bool UseFullInt64Range)
|
bool Orientation(OutRec *outRec, bool UseFullInt64Range)
|
||||||
{
|
{
|
||||||
|
//first make sure bottomPt is correctly assigned ...
|
||||||
OutPt *opBottom = outRec->pts, *op = outRec->pts->next;
|
OutPt *opBottom = outRec->pts, *op = outRec->pts->next;
|
||||||
while (op != outRec->pts)
|
while (op != outRec->pts)
|
||||||
{
|
{
|
||||||
|
@ -364,28 +371,28 @@ bool Orientation(OutRec *outRec, bool UseFullInt64Range)
|
||||||
}
|
}
|
||||||
op = op->next;
|
op = op->next;
|
||||||
}
|
}
|
||||||
|
outRec->bottomPt = opBottom;
|
||||||
|
opBottom->idx = outRec->idx;
|
||||||
|
|
||||||
IntPoint vec1, vec2;
|
op = opBottom;
|
||||||
vec1.X = op->pt.X - op->prev->pt.X;
|
//find vertices either side of bottomPt (skipping duplicate points) ....
|
||||||
vec1.Y = op->pt.Y - op->prev->pt.Y;
|
OutPt *opPrev = op->prev;
|
||||||
vec2.X = op->next->pt.X - op->pt.X;
|
OutPt *opNext = op->next;
|
||||||
vec2.Y = op->next->pt.Y - op->pt.Y;
|
while (op != opPrev && PointsEqual(op->pt, opPrev->pt))
|
||||||
|
opPrev = opPrev->prev;
|
||||||
|
while (op != opNext && PointsEqual(op->pt, opNext->pt))
|
||||||
|
opNext = opNext->next;
|
||||||
|
|
||||||
|
IntPoint ip1, ip2;
|
||||||
|
ip1.X = op->pt.X - opPrev->pt.X;
|
||||||
|
ip1.Y = op->pt.Y - opPrev->pt.Y;
|
||||||
|
ip2.X = opNext->pt.X - op->pt.X;
|
||||||
|
ip2.Y = opNext->pt.Y - op->pt.Y;
|
||||||
|
|
||||||
if (UseFullInt64Range)
|
if (UseFullInt64Range)
|
||||||
{
|
return Int128(ip1.X) * Int128(ip2.Y) - Int128(ip2.X) * Int128(ip1.Y) > 0;
|
||||||
Int128 cross = Int128(vec1.X) * Int128(vec2.Y) - Int128(vec2.X) * Int128(vec1.Y);
|
|
||||||
return cross > 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
return (ip1.X * ip2.Y - ip2.X * ip1.Y) > 0;
|
||||||
return (vec1.X * vec2.Y - vec2.X * vec1.Y) > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
inline bool PointsEqual( const IntPoint &pt1, const IntPoint &pt2)
|
|
||||||
{
|
|
||||||
return ( pt1.X == pt2.X && pt1.Y == pt2.Y );
|
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -473,9 +480,7 @@ bool PointInPolygon(const IntPoint &pt, OutPt *pp, bool UseFullInt64Range)
|
||||||
|
|
||||||
bool SlopesEqual(TEdge &e1, TEdge &e2, bool UseFullInt64Range)
|
bool SlopesEqual(TEdge &e1, TEdge &e2, bool UseFullInt64Range)
|
||||||
{
|
{
|
||||||
if (e1.ybot == e1.ytop) return (e2.ybot == e2.ytop);
|
if (UseFullInt64Range)
|
||||||
else if (e1.xbot == e1.xtop) return (e2.xbot == e2.xtop);
|
|
||||||
else if (UseFullInt64Range)
|
|
||||||
return Int128(e1.ytop - e1.ybot) * Int128(e2.xtop - e2.xbot) ==
|
return Int128(e1.ytop - e1.ybot) * Int128(e2.xtop - e2.xbot) ==
|
||||||
Int128(e1.xtop - e1.xbot) * Int128(e2.ytop - e2.ybot);
|
Int128(e1.xtop - e1.xbot) * Int128(e2.ytop - e2.ybot);
|
||||||
else return (e1.ytop - e1.ybot)*(e2.xtop - e2.xbot) ==
|
else return (e1.ytop - e1.ybot)*(e2.xtop - e2.xbot) ==
|
||||||
|
@ -486,9 +491,7 @@ bool SlopesEqual(TEdge &e1, TEdge &e2, bool UseFullInt64Range)
|
||||||
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
|
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
|
||||||
const IntPoint pt3, bool UseFullInt64Range)
|
const IntPoint pt3, bool UseFullInt64Range)
|
||||||
{
|
{
|
||||||
if (pt1.Y == pt2.Y) return (pt2.Y == pt3.Y);
|
if (UseFullInt64Range)
|
||||||
else if (pt1.X == pt2.X) return (pt2.X == pt3.X);
|
|
||||||
else if (UseFullInt64Range)
|
|
||||||
return Int128(pt1.Y-pt2.Y) * Int128(pt2.X-pt3.X) ==
|
return Int128(pt1.Y-pt2.Y) * Int128(pt2.X-pt3.X) ==
|
||||||
Int128(pt1.X-pt2.X) * Int128(pt2.Y-pt3.Y);
|
Int128(pt1.X-pt2.X) * Int128(pt2.Y-pt3.Y);
|
||||||
else return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y);
|
else return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y);
|
||||||
|
@ -498,9 +501,7 @@ bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
|
||||||
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
|
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
|
||||||
const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range)
|
const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range)
|
||||||
{
|
{
|
||||||
if (pt1.Y == pt2.Y) return (pt3.Y == pt4.Y);
|
if (UseFullInt64Range)
|
||||||
else if (pt1.X == pt2.X) return (pt3.X == pt4.X);
|
|
||||||
else if (UseFullInt64Range)
|
|
||||||
return Int128(pt1.Y-pt2.Y) * Int128(pt3.X-pt4.X) ==
|
return Int128(pt1.Y-pt2.Y) * Int128(pt3.X-pt4.X) ==
|
||||||
Int128(pt1.X-pt2.X) * Int128(pt3.Y-pt4.Y);
|
Int128(pt1.X-pt2.X) * Int128(pt3.Y-pt4.Y);
|
||||||
else return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y);
|
else return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y);
|
||||||
|
@ -1477,19 +1478,34 @@ bool Clipper::IsContributing(const TEdge& edge) const
|
||||||
|
|
||||||
void Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt)
|
void Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt)
|
||||||
{
|
{
|
||||||
|
TEdge *e, *prevE;
|
||||||
if( NEAR_EQUAL(e2->dx, HORIZONTAL) || ( e1->dx > e2->dx ) )
|
if( NEAR_EQUAL(e2->dx, HORIZONTAL) || ( e1->dx > e2->dx ) )
|
||||||
{
|
{
|
||||||
AddOutPt( e1, e2, pt );
|
AddOutPt( e1, e2, pt );
|
||||||
e2->outIdx = e1->outIdx;
|
e2->outIdx = e1->outIdx;
|
||||||
e1->side = esLeft;
|
e1->side = esLeft;
|
||||||
e2->side = esRight;
|
e2->side = esRight;
|
||||||
|
e = e1;
|
||||||
|
if (e->prevInAEL == e2)
|
||||||
|
prevE = e2->prevInAEL;
|
||||||
|
else
|
||||||
|
prevE = e->prevInAEL;
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
AddOutPt( e2, e1, pt );
|
AddOutPt( e2, e1, pt );
|
||||||
e1->outIdx = e2->outIdx;
|
e1->outIdx = e2->outIdx;
|
||||||
e1->side = esRight;
|
e1->side = esRight;
|
||||||
e2->side = esLeft;
|
e2->side = esLeft;
|
||||||
|
e = e2;
|
||||||
|
if (e->prevInAEL == e1)
|
||||||
|
prevE = e1->prevInAEL;
|
||||||
|
else
|
||||||
|
prevE = e->prevInAEL;
|
||||||
}
|
}
|
||||||
|
if (prevE && prevE->outIdx >= 0 &&
|
||||||
|
(TopX(*prevE, pt.Y) == TopX(*e, pt.Y)) &&
|
||||||
|
SlopesEqual(*e, *prevE, m_UseFullRange))
|
||||||
|
AddJoin(e, prevE, -1, -1);
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -1621,12 +1637,6 @@ void Clipper::InsertLocalMinimaIntoAEL( const long64 botY)
|
||||||
if( IsContributing(*lb) )
|
if( IsContributing(*lb) )
|
||||||
AddLocalMinPoly( lb, rb, IntPoint(lb->xcurr, m_CurrentLM->Y) );
|
AddLocalMinPoly( lb, rb, IntPoint(lb->xcurr, m_CurrentLM->Y) );
|
||||||
|
|
||||||
//if output polygons share an edge, they'll need joining later ...
|
|
||||||
if (lb->outIdx >= 0 && lb->prevInAEL &&
|
|
||||||
lb->prevInAEL->outIdx >= 0 && lb->prevInAEL->xcurr == lb->xbot &&
|
|
||||||
SlopesEqual(*lb, *lb->prevInAEL, m_UseFullRange))
|
|
||||||
AddJoin(lb, lb->prevInAEL);
|
|
||||||
|
|
||||||
//if any output polygons share an edge, they'll need joining later ...
|
//if any output polygons share an edge, they'll need joining later ...
|
||||||
if (rb->outIdx >= 0)
|
if (rb->outIdx >= 0)
|
||||||
{
|
{
|
||||||
|
@ -1819,8 +1829,8 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
|
||||||
AddLocalMinPoly(e1, e2, pt);
|
AddLocalMinPoly(e1, e2, pt);
|
||||||
break;
|
break;
|
||||||
case ctDifference:
|
case ctDifference:
|
||||||
if ( (e1->polyType == ptClip && e1Wc2 > 0 && e2Wc2 > 0) ||
|
if (e1->polyType == ptClip && e1Wc2 > 0 && e2Wc2 > 0 ||
|
||||||
(e1->polyType == ptSubject && e1Wc2 <= 0 && e2Wc2 <= 0) )
|
e1->polyType == ptSubject && e1Wc2 <= 0 && e2Wc2 <= 0)
|
||||||
AddLocalMinPoly(e1, e2, pt);
|
AddLocalMinPoly(e1, e2, pt);
|
||||||
break;
|
break;
|
||||||
case ctXor:
|
case ctXor:
|
||||||
|
@ -2976,14 +2986,28 @@ void Clipper::JoinCommonEdges(bool fixHoleLinkages)
|
||||||
//make sure any holes contained by outRec2 now link to outRec1 ...
|
//make sure any holes contained by outRec2 now link to outRec1 ...
|
||||||
if (fixHoleLinkages) CheckHoleLinkages2(outRec1, outRec2);
|
if (fixHoleLinkages) CheckHoleLinkages2(outRec1, outRec2);
|
||||||
|
|
||||||
|
//since it's possible for outRec2->bottomPt to be cleaned up
|
||||||
|
//in FixupOutPolygon() below, we need to keep a copy of it ...
|
||||||
|
IntPoint ip = outRec2->bottomPt->pt;
|
||||||
|
|
||||||
|
//now cleanup redundant edges too ...
|
||||||
|
FixupOutPolygon(*outRec1);
|
||||||
|
|
||||||
|
if (outRec1->pts) {
|
||||||
|
//sort out hole vs outer and then recheck orientation ...
|
||||||
|
if (outRec1->isHole != outRec2->isHole && (ip.Y > outRec1->bottomPt->pt.Y ||
|
||||||
|
(ip.Y == outRec1->bottomPt->pt.Y && ip.X < outRec1->bottomPt->pt.X)))
|
||||||
|
outRec1->isHole = outRec2->isHole;
|
||||||
|
if (outRec1->isHole == Orientation(outRec1, m_UseFullRange))
|
||||||
|
ReversePolyPtLinks(*outRec1->pts);
|
||||||
|
}
|
||||||
|
|
||||||
//delete the obsolete pointer ...
|
//delete the obsolete pointer ...
|
||||||
int OKIdx = outRec1->idx;
|
int OKIdx = outRec1->idx;
|
||||||
int ObsoleteIdx = outRec2->idx;
|
int ObsoleteIdx = outRec2->idx;
|
||||||
outRec2->pts = 0;
|
outRec2->pts = 0;
|
||||||
outRec2->bottomPt = 0;
|
outRec2->bottomPt = 0;
|
||||||
outRec2->AppendLink = outRec1;
|
outRec2->AppendLink = outRec1;
|
||||||
//holes are practically always joined to outers, not vice versa ...
|
|
||||||
if (outRec1->isHole && !outRec2->isHole) outRec1->isHole = false;
|
|
||||||
|
|
||||||
//now fixup any subsequent Joins that match this polygon
|
//now fixup any subsequent Joins that match this polygon
|
||||||
for (JoinList::size_type k = i+1; k < m_Joins.size(); k++)
|
for (JoinList::size_type k = i+1; k < m_Joins.size(); k++)
|
||||||
|
@ -2992,12 +3016,6 @@ void Clipper::JoinCommonEdges(bool fixHoleLinkages)
|
||||||
if (j2->poly1Idx == ObsoleteIdx) j2->poly1Idx = OKIdx;
|
if (j2->poly1Idx == ObsoleteIdx) j2->poly1Idx = OKIdx;
|
||||||
if (j2->poly2Idx == ObsoleteIdx) j2->poly2Idx = OKIdx;
|
if (j2->poly2Idx == ObsoleteIdx) j2->poly2Idx = OKIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
//now cleanup redundant edges too ...
|
|
||||||
if (outRec1->pts)
|
|
||||||
FixupOutPolygon(*outRec1);
|
|
||||||
else
|
|
||||||
FixupOutPolygon(*outRec2);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* *
|
* *
|
||||||
* Author : Angus Johnson *
|
* Author : Angus Johnson *
|
||||||
* Version : 4.6.5 *
|
* Version : 4.7.3 *
|
||||||
* Date : 17 January 2011 *
|
* Date : 7 March 2012 *
|
||||||
* Website : http://www.angusj.com *
|
* Website : http://www.angusj.com *
|
||||||
* Copyright : Angus Johnson 2010-2012 *
|
* Copyright : Angus Johnson 2010-2012 *
|
||||||
* *
|
* *
|
||||||
|
@ -73,7 +73,7 @@ struct ExPolygon {
|
||||||
};
|
};
|
||||||
typedef std::vector< ExPolygon > ExPolygons;
|
typedef std::vector< ExPolygon > ExPolygons;
|
||||||
|
|
||||||
enum JoinType { jtSquare, jtMiter, jtRound };
|
enum JoinType { jtSquare, jtRound, jtMiter };
|
||||||
|
|
||||||
bool Orientation(const Polygon &poly);
|
bool Orientation(const Polygon &poly);
|
||||||
double Area(const Polygon &poly);
|
double Area(const Polygon &poly);
|
||||||
|
|
Loading…
Reference in a new issue