53static double const pi = 3.141592653589793238;
62#define HORIZONTAL (-1.0E+40)
63#define TOLERANCE (1.0e-20)
64#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE))
129 return locMin2.
Y < locMin1.
Y;
138 if ((val < 0))
return static_cast<cInt>(val - 0.5);
139 else return static_cast<cInt>(val + 0.5);
145 return val < 0 ? -val : val;
154 for (PolyNodes::size_type
i = 0;
i <
AllNodes.size(); ++
i)
189 return (
int)
Childs.size();
195 unsigned cnt = (unsigned)
Childs.size();
260 if (_lo < 0)
hi = -1;
else hi = 0;
271 if (val < 0)
hi = -1;
else hi = 0;
276 {
return (
hi == val.
hi &&
lo == val.
lo);}
279 {
return !(*
this == val);}
298 {
return !(*
this < val);}
301 {
return !(*
this > val);}
341 const double shift64 = 18446744073709551616.0;
344 if (
lo == 0)
return (
double)
hi * shift64;
348 return (
double)(
lo +
hi * shift64);
356 bool negate = (lhs < 0) != (rhs < 0);
358 if (lhs < 0) lhs = -lhs;
362 if (rhs < 0) rhs = -rhs;
369 ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi;
375 if (tmp.
lo < b) tmp.
hi++;
376 if (negate) tmp = -tmp;
387 return Area(poly) >= 0;
393 int size = (int)poly.size();
394 if (size < 3)
return 0;
397 for (
int i = 0,
j = size -1;
i < size; ++
i)
408 const OutPt *startOp = op;
414 }
while (op != startOp);
430 if (pp2->
Pt == Pt)
return true;
444 size_t cnt = path.size();
445 if (cnt < 3)
return 0;
447 for(
size_t i = 1;
i <= cnt; ++
i)
449 IntPoint ipNext = (
i == cnt ? path[0] : path[
i]);
450 if (ipNext.
Y == pt.
Y)
452 if ((ipNext.
X == pt.
X) || (ip.
Y == pt.
Y &&
453 ((ipNext.
X > pt.
X) == (ip.
X < pt.
X))))
return -1;
455 if ((ip.
Y < pt.
Y) != (ipNext.
Y < pt.
Y))
459 if (ipNext.
X > pt.
X) result = 1 - result;
462 double d = (
double)(ip.
X - pt.
X) * (ipNext.
Y - pt.
Y) -
463 (
double)(ipNext.
X - pt.
X) * (ip.
Y - pt.
Y);
465 if ((d > 0) == (ipNext.
Y > ip.
Y)) result = 1 - result;
471 double d = (
double)(ip.
X - pt.
X) * (ipNext.
Y - pt.
Y) -
472 (
double)(ipNext.
X - pt.
X) * (ip.
Y - pt.
Y);
474 if ((d > 0) == (ipNext.
Y > ip.
Y)) result = 1 - result;
494 ((op->
Next->
Pt.
X > pt.
X) == (op->
Pt.
X < pt.
X))))
return -1;
498 if (op->
Pt.
X >= pt.
X)
500 if (op->
Next->
Pt.
X > pt.
X) result = 1 - result;
506 if ((d > 0) == (op->
Next->
Pt.
Y > op->
Pt.
Y)) result = 1 - result;
515 if ((d > 0) == (op->
Next->
Pt.
Y > op->
Pt.
Y)) result = 1 - result;
520 if (startOp == op)
break;
533 if (res >= 0)
return res > 0;
536 while (op != OutPt1);
544 if (UseFullInt64Range)
555 const IntPoint pt3,
bool UseFullInt64Range)
558 if (UseFullInt64Range)
562 return (pt1.
Y-pt2.
Y)*(pt2.
X-pt3.
X) == (pt1.
X-pt2.
X)*(pt2.
Y-pt3.
Y);
570 if (UseFullInt64Range)
574 return (pt1.
Y-pt2.
Y)*(pt3.
X-pt4.
X) == (pt1.
X-pt2.
X)*(pt3.
Y-pt4.
Y);
586 return (pt1.
Y == pt2.
Y) ?
609 int OutIdx = Edge1.
OutIdx;
617 return ( currentY == edge.
Top.
Y ) ?
629 if (Edge1.
Dx == Edge2.
Dx)
635 else if (Edge1.
Dx == 0)
646 else if (Edge2.
Dx == 0)
661 double q = (b2-b1) / (Edge1.
Dx - Edge2.
Dx);
663 if (std::fabs(Edge1.
Dx) < std::fabs(Edge2.
Dx))
675 if (std::fabs(Edge1.
Dx) < std::fabs(Edge2.
Dx))
685 if (std::fabs(Edge1.
Dx) > std::fabs(Edge2.
Dx))
686 ip.
X =
TopX(Edge2, ip.
Y);
else
702 }
while( pp1 != pp );
721 std::memset(e, 0,
sizeof(
TEdge));
763 std::swap(e.
Top.Z, e.
Bot.Z);
780 if (
Abs(pt1a.
X - pt1b.
X) >
Abs(pt1a.
Y - pt1b.
Y))
784 if (pt1a.
X > pt2a.
X) pt1 = pt1a;
else pt1 = pt2a;
785 if (pt1b.
X < pt2b.
X) pt2 = pt1b;
else pt2 = pt2b;
786 return pt1.
X < pt2.
X;
791 if (pt1a.
Y < pt2a.
Y) pt1 = pt1a;
else pt1 = pt2a;
792 if (pt1b.
Y > pt2b.
Y) pt2 = pt1b;
else pt2 = pt2b;
793 return pt1.
Y > pt2.
Y;
801 while ((
p->Pt == btmPt1->
Pt) && (
p != btmPt1))
p =
p->Prev;
802 double dx1p = std::fabs(
GetDx(btmPt1->
Pt,
p->Pt));
804 while ((
p->Pt == btmPt1->
Pt) && (
p != btmPt1))
p =
p->Next;
805 double dx1n = std::fabs(
GetDx(btmPt1->
Pt,
p->Pt));
808 while ((
p->Pt == btmPt2->
Pt) && (
p != btmPt2))
p =
p->Prev;
809 double dx2p = std::fabs(
GetDx(btmPt2->
Pt,
p->Pt));
811 while ((
p->Pt == btmPt2->
Pt) && (
p != btmPt2))
p =
p->Next;
812 double dx2n = std::fabs(
GetDx(btmPt2->
Pt,
p->Pt));
814 if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
815 std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
816 return Area(btmPt1) > 0;
818 return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
828 if (
p->Pt.Y > pp->
Pt.
Y)
833 else if (
p->Pt.Y == pp->
Pt.
Y &&
p->Pt.X <= pp->
Pt.
X)
835 if (
p->Pt.X < pp->
Pt.
X)
841 if (
p->Next != pp &&
p->Prev != pp) dups =
p;
853 while (dups->
Pt != pp->
Pt) dups = dups->
Next;
863 if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2))
865 else if (pt1.
X != pt3.
X)
866 return (pt2.
X > pt1.
X) == (pt2.
X < pt3.
X);
868 return (pt2.
Y > pt1.
Y) == (pt2.
Y < pt3.
Y);
874 if (seg1a > seg1b) std::swap(seg1a, seg1b);
875 if (seg2a > seg2b) std::swap(seg2a, seg2b);
876 return (seg1a < seg2b) && (seg2a < seg1b);
915 while (
E->Bot !=
E->Prev->Bot ||
E->Curr ==
E->Top)
E =
E->Next;
920 if (
E->Top.Y ==
E->Prev->Bot.Y)
continue;
933 if (
E->OutIdx ==
Skip)
939 while (
E->Top.Y ==
E->Next->Bot.Y)
E =
E->Next;
946 while (
E->Top.Y ==
E->Prev->Bot.Y)
E =
E->Prev;
952 if (NextIsForward) Result =
E->Next;
953 else Result =
E->Prev;
962 MinimaList::value_type locMin;
964 locMin.LeftBound = 0;
965 locMin.RightBound =
E;
986 if (EStart->
Bot.
X !=
E->Bot.X && EStart->
Top.
X !=
E->Bot.X)
989 else if (EStart->
Bot.
X !=
E->Bot.X)
997 Result = Result->
Next;
1009 E->NextInLML =
E->Next;
1016 Result = Result->
Next;
1020 Result = Result->
Prev;
1031 E->NextInLML =
E->Prev;
1038 Result = Result->
Prev;
1048 if (!Closed && PolyTyp ==
ptClip)
1055 int highI = (int)pg.size() -1;
1056 if (Closed)
while (highI > 0 && (pg[highI] == pg[0])) --highI;
1057 while (highI > 0 && (pg[highI] == pg[highI -1])) --highI;
1058 if ((Closed && highI < 2) || (!Closed && highI < 1))
return false;
1067 edges[1].
Curr = pg[1];
1070 InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]);
1071 InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]);
1072 for (
int i = highI - 1;
i >= 1; --
i)
1083 TEdge *eStart = &edges[0];
1086 TEdge *
E = eStart, *eLoopStop = eStart;
1090 if (
E->Curr ==
E->Next->Curr && (Closed ||
E->Next != eStart))
1092 if (
E ==
E->Next)
break;
1093 if (
E == eStart) eStart =
E->Next;
1098 if (
E->Prev ==
E->Next)
1109 if (
E == eStart) eStart =
E->Next;
1116 if ((
E == eLoopStop) || (!Closed &&
E->Next == eStart))
break;
1119 if ((!Closed && (
E ==
E->Next)) || (Closed && (
E->Prev ==
E->Next)))
1137 if (IsFlat &&
E->Curr.Y != eStart->
Curr.
Y) IsFlat =
false;
1139 while (
E != eStart);
1152 E->Prev->OutIdx =
Skip;
1153 MinimaList::value_type locMin;
1154 locMin.Y =
E->Bot.Y;
1155 locMin.LeftBound = 0;
1156 locMin.RightBound =
E;
1157 locMin.RightBound->Side =
esRight;
1158 locMin.RightBound->WindDelta = 0;
1162 if (
E->Next->OutIdx ==
Skip)
break;
1163 E->NextInLML =
E->Next;
1172 bool leftBoundIsForward;
1177 if (
E->Prev->Bot ==
E->Prev->Top)
E =
E->Next;
1182 if (
E == EMin)
break;
1183 else if (!EMin) EMin =
E;
1187 MinimaList::value_type locMin;
1188 locMin.Y =
E->Bot.Y;
1189 if (
E->Dx <
E->Prev->Dx)
1191 locMin.LeftBound =
E->Prev;
1192 locMin.RightBound =
E;
1193 leftBoundIsForward =
false;
1196 locMin.LeftBound =
E;
1197 locMin.RightBound =
E->Prev;
1198 leftBoundIsForward =
true;
1201 if (!Closed) locMin.LeftBound->WindDelta = 0;
1202 else if (locMin.LeftBound->Next == locMin.RightBound)
1203 locMin.LeftBound->WindDelta = -1;
1204 else locMin.LeftBound->WindDelta = 1;
1205 locMin.RightBound->WindDelta = -locMin.LeftBound->WindDelta;
1213 if (locMin.LeftBound->OutIdx ==
Skip)
1214 locMin.LeftBound = 0;
1215 else if (locMin.RightBound->OutIdx ==
Skip)
1216 locMin.RightBound = 0;
1218 if (!leftBoundIsForward)
E = E2;
1226 bool result =
false;
1227 for (Paths::size_type
i = 0;
i < ppg.size(); ++
i)
1228 if (
AddPath(ppg[
i], PolyTyp, Closed)) result =
true;
1236 for (EdgeList::size_type
i = 0;
i <
m_edges.size(); ++
i)
1258 TEdge* e = lm->LeftBound;
1289 locMin = &(*m_CurrentLM);
1304 result.
left = lm->LeftBound->Bot.X;
1305 result.
top = lm->LeftBound->Bot.Y;
1306 result.
right = lm->LeftBound->Bot.X;
1307 result.
bottom = lm->LeftBound->Bot.Y;
1311 result.
bottom = std::max(result.
bottom, lm->LeftBound->Bot.Y);
1312 TEdge* e = lm->LeftBound;
1326 if (bottomE == lm->LeftBound) e = lm->RightBound;
1352 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size(); ++
i)
1372 if (AelPrev) AelPrev->
NextInAEL = AelNext;
1374 if (AelNext) AelNext->
PrevInAEL = AelPrev;
1489void Clipper::ZFillFunction(ZFillCallback zFillFunc)
1491 m_ZFill = zFillFunc;
1498 return Execute(clipType, solution, fillType, fillType);
1504 return Execute(clipType, polytree, fillType, fillType);
1513 throw clipperException(
"Error: PolyTree struct is needed for open path clipping.");
1562 bool succeeded =
true;
1594 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size(); ++
i)
1597 if (!outRec->
Pts || outRec->
IsOpen)
continue;
1605 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size(); ++
i)
1608 if (!outRec->
Pts)
continue;
1661 edge.
WindCnt = (Inside ? 0 : 1);
1716 while ( e != &edge )
1764 if (edge.
WindCnt != 1)
return false;
1767 if (edge.
WindCnt != -1)
return false;
1869 if (prevE && prevE->
OutIdx >= 0)
1954 for (JoinList::size_type
i = 0;
i <
m_Joins.size();
i++)
2026 if (!lb || !rb)
continue;
2085 if( SelPrev ) SelPrev->
NextInSEL = SelNext;
2087 if( SelNext ) SelNext->
PrevInSEL = SelPrev;
2096 if (pt.Z != 0 || !m_ZFill)
return;
2097 else if (pt == e1.
Bot) pt.Z = e1.
Bot.Z;
2098 else if (pt == e1.
Top) pt.Z = e1.
Top.Z;
2099 else if (pt == e2.
Bot) pt.Z = e2.
Bot.Z;
2100 else if (pt == e2.
Top) pt.Z = e2.
Top.Z;
2108 bool e1Contributing = ( e1->
OutIdx >= 0 );
2109 bool e2Contributing = ( e2->
OutIdx >= 0 );
2170 int oldE1WindCnt = e1->
WindCnt;
2188 PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
2222 if ( e1Contributing && e2Contributing )
2224 if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
2237 else if ( e1Contributing )
2239 if (e2Wc == 0 || e2Wc == 1)
2246 else if ( e2Contributing )
2248 if (e1Wc == 0 || e1Wc == 1)
2255 else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1))
2260 switch (e1FillType2)
2266 switch (e2FillType2)
2277 else if (e1Wc == 1 && e2Wc == 1)
2280 if (e1Wc2 > 0 && e2Wc2 > 0)
2284 if ( e1Wc2 <= 0 && e2Wc2 <= 0 )
2288 if (((e1->
PolyTyp ==
ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
2309 if (!eTmp) eTmp = e2;
2336 if (OutPt1->
Pt.
Y > OutPt2->
Pt.
Y)
return outRec1;
2337 else if (OutPt1->
Pt.
Y < OutPt2->
Pt.
Y)
return outRec2;
2338 else if (OutPt1->
Pt.
X < OutPt2->
Pt.
X)
return outRec1;
2339 else if (OutPt1->
Pt.
X > OutPt2->
Pt.
X)
return outRec2;
2340 else if (OutPt1->
Next == OutPt1)
return outRec2;
2341 else if (OutPt2->
Next == OutPt2)
return outRec1;
2343 else return outRec2;
2352 if (outRec1 == outRec2)
return true;
2375 holeStateRec = outRec2;
2377 holeStateRec = outRec1;
2396 p2_lft->
Next = p1_lft;
2397 p1_lft->
Prev = p2_lft;
2398 p1_rt->
Next = p2_rt;
2399 p2_rt->
Prev = p1_rt;
2400 outRec1->
Pts = p2_rt;
2404 p2_rt->
Next = p1_lft;
2405 p1_lft->
Prev = p2_rt;
2406 p2_lft->
Prev = p1_rt;
2407 p1_rt->
Next = p2_lft;
2408 outRec1->
Pts = p2_lft;
2416 p1_rt->
Next = p2_rt;
2417 p2_rt->
Prev = p1_rt;
2418 p2_lft->
Next = p1_lft;
2419 p1_lft->
Prev = p2_lft;
2423 p1_rt->
Next = p2_lft;
2424 p2_lft->
Prev = p1_rt;
2425 p1_lft->
Prev = p2_rt;
2426 p2_rt->
Next = p1_lft;
2431 if (holeStateRec == outRec2)
2442 int ObsoleteIdx = e2->
OutIdx;
2450 if( e->
OutIdx == ObsoleteIdx )
2459 outRec2->
Idx = outRec1->
Idx;
2470 outRec->
Pts = newOp;
2471 newOp->
Idx = outRec->
Idx;
2473 newOp->
Next = newOp;
2474 newOp->
Prev = newOp;
2486 if (ToFront && (pt == op->
Pt))
return op;
2487 else if (!ToFront && (pt == op->
Prev->
Pt))
return op->
Prev;
2490 newOp->
Idx = outRec->
Idx;
2496 if (ToFront) outRec->
Pts = newOp;
2612 if (HorzEdge.
Bot.
X < HorzEdge.
Top.
X)
2614 Left = HorzEdge.
Bot.
X;
2615 Right = HorzEdge.
Top.
X;
2619 Left = HorzEdge.
Top.
X;
2620 Right = HorzEdge.
Bot.
X;
2639 cInt horzLeft, horzRight;
2640 bool IsOpen = (horzEdge->
WindDelta == 0);
2644 TEdge* eLastHorz = horzEdge, *eMaxPair = 0;
2650 MaximaList::const_iterator maxIt;
2651 MaximaList::const_reverse_iterator maxRit;
2658 while (maxIt !=
m_Maxima.end() && *maxIt <= horzEdge->Bot.X) maxIt++;
2659 if (maxIt !=
m_Maxima.end() && *maxIt >= eLastHorz->
Top.
X)
2665 while (maxRit !=
m_Maxima.rend() && *maxRit > horzEdge->
Bot.
X) maxRit++;
2666 if (maxRit !=
m_Maxima.rend() && *maxRit <= eLastHorz->Top.X)
2676 bool IsLastHorz = (horzEdge == eLastHorz);
2688 while (maxIt !=
m_Maxima.end() && *maxIt < e->Curr.X)
2690 if (horzEdge->
OutIdx >= 0 && !IsOpen)
2699 if (horzEdge->
OutIdx >= 0 && !IsOpen)
2714 if (horzEdge->
OutIdx >= 0 && !IsOpen)
2720 if (eNextHorz->
OutIdx >= 0 &&
2734 if(e == eMaxPair && IsLastHorz)
2736 if (horzEdge->
OutIdx >= 0)
2767 if (horzEdge->
OutIdx >= 0 && !op1)
2773 if (eNextHorz->
OutIdx >= 0 &&
2787 if(horzEdge->
OutIdx >= 0)
2795 if (ePrev && ePrev->
Curr.
X == horzEdge->
Bot.
X &&
2803 else if (eNext && eNext->
Curr.
X == horzEdge->
Bot.
X &&
2829 if (IlSize == 0)
return true;
2883 newNode->
Edge2 = eNext;
2896 while ( isModified );
2919 return node2->
Pt.
Y < node1->
Pt.
Y;
2938 for (
size_t i = 0;
i < cnt; ++
i)
2944 if (
j == cnt)
return false;
2965 while(eNext && eNext != eMaxPair)
2993 if (eMaxPair->
OutIdx >= 0)
3012 bool IsMaximaEdge =
IsMaxima(e, topY);
3017 IsMaximaEdge = (!eMaxPair || !
IsHorizontal(*eMaxPair));
3054 SetZ(pt, *ePrev, *e);
3085 if (ePrev && ePrev->
Curr.
X == e->
Bot.
X &&
3094 else if (eNext && eNext->
Curr.
X == e->
Bot.
X &&
3113 while (pp != lastPP)
3118 if (pp == lastPP) lastPP = pp->
Prev;
3166 else if (pp == lastOK)
break;
3169 if (!lastOK) lastOK = pp;
3195 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size(); ++
i)
3201 if (cnt < 2)
continue;
3203 for (
int i = 0;
i < cnt; ++
i)
3205 pg.push_back(
p->Pt);
3208 polys.push_back(pg);
3218 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size();
i++)
3222 if ((outRec->
IsOpen && cnt < 2) || (!outRec->
IsOpen && cnt < 3))
continue;
3232 for (
int j = 0;
j < cnt;
j++)
3241 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size();
i++)
3244 if (!outRec->
PolyNd)
continue;
3288 if (b1 < b2) {Left = std::max(
a1,b1); Right = std::min(
a2,b2);}
3289 else {Left = std::max(
a1,b2); Right = std::min(
a2,b1);}
3293 if (b1 < b2) {Left = std::max(
a2,b1); Right = std::min(
a1,b2);}
3294 else {Left = std::max(
a2,b2); Right = std::min(
a1,b1);}
3296 return Left < Right;
3308 while(op != outrec.
Pts);
3344 result->
Pt = outPt->
Pt;
3345 result->
Idx = outPt->
Idx;
3349 result->
Prev = outPt;
3351 outPt->
Next = result;
3356 result->
Next = outPt;
3358 outPt->
Prev = result;
3365 const IntPoint Pt,
bool DiscardLeft)
3369 if (Dir1 == Dir2)
return false;
3381 if (DiscardLeft && (op1->
Pt.
X != Pt.
X)) op1 = op1->
Next;
3382 op1b =
DupOutPt(op1, !DiscardLeft);
3387 op1b =
DupOutPt(op1, !DiscardLeft);
3395 if (!DiscardLeft && (op1->
Pt.
X != Pt.
X)) op1 = op1->
Next;
3410 if (DiscardLeft && (op2->
Pt.
X != Pt.
X)) op2 = op2->
Next;
3411 op2b =
DupOutPt(op2, !DiscardLeft);
3416 op2b =
DupOutPt(op2, !DiscardLeft);
3423 if (!DiscardLeft && (op2->
Pt.
X != Pt.
X)) op2 = op2->
Next;
3453 OutPt *op1 =
j->OutPt1, *op1b;
3454 OutPt *op2 =
j->OutPt2, *op2b;
3463 bool isHorizontal = (
j->OutPt1->Pt.Y ==
j->OffPt.Y);
3465 if (isHorizontal && (
j->OffPt ==
j->OutPt1->Pt) &&
3466 (
j->OffPt ==
j->OutPt2->Pt))
3469 if (outRec1 != outRec2)
return false;
3470 op1b =
j->OutPt1->Next;
3471 while (op1b != op1 && (op1b->Pt ==
j->OffPt))
3473 bool reverse1 = (op1b->Pt.Y >
j->OffPt.Y);
3474 op2b =
j->OutPt2->Next;
3475 while (op2b != op2 && (op2b->Pt ==
j->OffPt))
3477 bool reverse2 = (op2b->Pt.Y >
j->OffPt.Y);
3478 if (reverse1 == reverse2)
return false;
3503 else if (isHorizontal)
3511 while (op1b->Next->Pt.Y == op1b->Pt.Y && op1b->Next != op1 && op1b->
Next != op2)
3513 if (op1b->Next == op1 || op1b->
Next == op2)
return false;
3518 while (op2b->Next->Pt.Y == op2b->Pt.Y && op2b->Next != op2 && op2b->
Next != op1)
3520 if (op2b->Next == op2 || op2b->
Next == op1)
return false;
3524 if (!
GetOverlap(op1->
Pt.
X, op1b->Pt.X, op2->
Pt.
X, op2b->Pt.X, Left, Right))
3531 bool DiscardLeftSide;
3532 if (op1->
Pt.
X >= Left && op1->
Pt.
X <= Right)
3534 Pt = op1->
Pt; DiscardLeftSide = (op1->
Pt.
X > op1b->Pt.X);
3536 else if (op2->
Pt.
X >= Left&& op2->
Pt.
X <= Right)
3538 Pt = op2->
Pt; DiscardLeftSide = (op2->
Pt.
X > op2b->Pt.X);
3540 else if (op1b->Pt.X >= Left && op1b->Pt.X <= Right)
3542 Pt = op1b->Pt; DiscardLeftSide = op1b->Pt.X > op1->
Pt.
X;
3546 Pt = op2b->Pt; DiscardLeftSide = (op2b->Pt.X > op2->
Pt.
X);
3548 j->OutPt1 = op1;
j->OutPt2 = op2;
3549 return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide);
3558 while ((op1b->Pt == op1->
Pt) && (op1b != op1)) op1b = op1b->
Next;
3559 bool Reverse1 = ((op1b->Pt.Y > op1->
Pt.
Y) ||
3564 while ((op1b->Pt == op1->
Pt) && (op1b != op1)) op1b = op1b->
Prev;
3565 if ((op1b->Pt.Y > op1->
Pt.
Y) ||
3569 while ((op2b->Pt == op2->
Pt) && (op2b != op2))op2b = op2b->
Next;
3570 bool Reverse2 = ((op2b->Pt.Y > op2->
Pt.
Y) ||
3575 while ((op2b->Pt == op2->
Pt) && (op2b != op2)) op2b = op2b->
Prev;
3576 if ((op2b->Pt.Y > op2->
Pt.
Y) ||
3580 if ((op1b == op1) || (op2b == op2) || (op1b == op2b) ||
3581 ((outRec1 == outRec2) && (Reverse1 == Reverse2)))
return false;
3612 while (FirstLeft && !FirstLeft->
Pts)
3621 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size(); ++
i)
3625 if (outRec->
Pts && firstLeft == OldOutRec)
3641 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size(); ++
i)
3645 if (!outRec->
Pts || outRec == OuterOutRec || outRec == InnerOutRec)
3648 if (firstLeft != orfl && firstLeft != InnerOutRec && firstLeft != OuterOutRec)
3662 for (PolyOutList::size_type
i = 0;
i <
m_PolyOuts.size(); ++
i)
3674 for (JoinList::size_type
i = 0;
i <
m_Joins.size();
i++)
3681 if (!outRec1->
Pts || !outRec2->
Pts)
continue;
3687 if (outRec1 == outRec2) holeStateRec = outRec1;
3692 if (!
JoinPoints(join, outRec1, outRec2))
continue;
3694 if (outRec1 == outRec2)
3746 outRec2->
Idx = outRec1->
Idx;
3749 if (holeStateRec == outRec2)
3764 if(pt2.
X == pt1.
X && pt2.
Y == pt1.
Y)
3767 double Dx = (
double)(pt2.
X - pt1.
X);
3768 double dy = (
double)(pt2.
Y - pt1.
Y);
3769 double f = 1 *1.0/ std::sqrt( Dx*Dx + dy*dy );
3804 int highI = (int)path.size() - 1;
3805 if (highI < 0)
return;
3812 while (highI > 0 && path[0] == path[highI]) highI--;
3813 newNode->
Contour.reserve(highI + 1);
3814 newNode->
Contour.push_back(path[0]);
3816 for (
int i = 1;
i <= highI;
i++)
3820 newNode->
Contour.push_back(path[
i]);
3821 if (path[
i].Y > newNode->
Contour[
k].Y ||
3849 for (Paths::size_type
i = 0;
i < paths.size(); ++
i)
3850 AddPath(paths[
i], joinType, endType);
3897 outer[0] =
IntPoint(r.left - 10, r.bottom + 10);
3898 outer[1] =
IntPoint(r.right + 10, r.bottom + 10);
3899 outer[2] =
IntPoint(r.right + 10, r.top - 10);
3900 outer[3] =
IntPoint(r.left - 10, r.top - 10);
3905 if (solution.size() > 0) solution.erase(solution.begin());
3927 outer[0] =
IntPoint(r.left - 10, r.bottom + 10);
3928 outer[1] =
IntPoint(r.right + 10, r.bottom + 10);
3929 outer[2] =
IntPoint(r.right + 10, r.top - 10);
3930 outer[3] =
IntPoint(r.left - 10, r.top - 10);
3979 double steps =
pi / std::acos(1 - y / std::fabs(
delta));
3980 if (steps > std::fabs(
delta) *
pi)
3981 steps = std::fabs(
delta) *
pi;
4002 double X = 1.0, Y = 0.0;
4003 for (
cInt j = 1;
j <= steps;
j++)
4015 double X = -1.0, Y = -1.0;
4016 for (
int j = 0;
j < 4; ++
j)
4022 else if (Y < 0) Y = 1;
4032 for (
int j = 0;
j < len - 1; ++
j)
4042 for (
int j = 0;
j < len; ++
j)
4049 for (
int j = 0;
j < len; ++
j)
4055 for (
int j = len - 1;
j > 0;
j--)
4059 for (
int j = len - 1;
j >= 0;
j--)
4066 for (
int j = 1;
j < len - 1; ++
j)
4093 for (
int j = len - 1;
j > 0;
j--)
4170 double dx = std::tan(std::atan2(
m_sinA,