Пример #1
0
 private static void ReversePolyPtLinks(OutPt pp)
 {
     if (pp == null)
         return;
     var pp1 = pp;
     do
     {
         var pp2 = pp1.Next;
         pp1.Next = pp1.Prev;
         pp1.Prev = pp2;
         pp1 = pp2;
     } while (pp1 != pp);
 }
Пример #2
0
        private void AddOutPt(TEdge e, IntPoint pt)
        {
            Contract.Requires(e != null);
            Contract.Requires(e.OutIdx < 0 || e.OutIdx < _polyOuts.Count);

            var toFront = e.Side == EdgeSide.Left;
            if (e.OutIdx < 0)
            {
                var outRec = CreateOutRec();
                e.OutIdx = outRec.Idx;
                var op = new OutPt();
                outRec.Pts = op;
                op.Pt = pt;
                op.Next = op;
                op.Prev = op;
                SetHoleState(e, outRec);
            }
            else
            {
                var outRec = _polyOuts[e.OutIdx];
                var op = outRec.Pts;
                if (toFront && pt.Equals(op.Pt) ||
                    (!toFront && pt.Equals(op.Prev.Pt)))
                    return;

                var op2 = new OutPt {
                    Pt = pt,
                    Next = op,
                    Prev = op.Prev
                };
                op2.Prev.Next = op2;
                op.Prev = op2;
                if (toFront)
                    outRec.Pts = op2;
            }
        }
Пример #3
0
        private static int PointCount(OutPt pts)
        {
            if (pts == null)
                return 0;

            var result = 0;
            var p = pts;
            do
            {
                result++;
                p = p.Next;
            } while (p != pts);
            return result;
        }
Пример #4
0
        private static bool Poly2ContainsPoly1(OutPt outPt1, OutPt outPt2)
        {
            Contract.Requires(outPt1 != null);
            Contract.Requires(outPt2 != null);

            var pt = outPt1;
            //Because the polygons may be touching, we need to find a vertex that
            //isn't touching the other polygon ...
            if (InternalHelpers.PointOnPolygon(pt.Pt, outPt2))
            {
                pt = pt.Next;
                while (pt != outPt1 && InternalHelpers.PointOnPolygon(pt.Pt, outPt2))
                    pt = pt.Next;
                if (pt == outPt1)
                    return true;
            }
            return InternalHelpers.PointInPolygon(pt.Pt, outPt2);
        }
Пример #5
0
        private static OutPt InsertPolyPtBetween(OutPt p1, OutPt p2, IntPoint pt)
        {
            Contract.Requires(p1 != null);
            Contract.Requires(p2 != null);
            Contract.Ensures(Contract.Result<OutPt>() != null);

            var result = new OutPt {Pt = pt};
            if (p2 == p1.Next)
            {
                p1.Next = result;
                p2.Prev = result;
                result.Next = p2;
                result.Prev = p1;
            }
            else
            {
                p2.Next = result;
                p1.Prev = result;
                result.Next = p1;
                result.Prev = p2;
            }
            return result;
        }
Пример #6
0
 private static bool FindSegment(ref OutPt pp, ref IntPoint pt1, ref IntPoint pt2)
 {
     if (pp == null)
         return false;
     var pp2 = pp;
     var pt1A = pt1;
     var pt2A = pt2;
     do
     {
         if (InternalHelpers.SlopesEqual(pt1A, pt2A, pp.Pt, pp.Prev.Pt) &&
             InternalHelpers.SlopesEqual(pt1A, pt2A, pp.Pt) &&
             GetOverlapSegment(pt1A, pt2A, pp.Pt, pp.Prev.Pt, out pt1, out pt2))
             return true;
         pp = pp.Next;
     } while (pp != pp2);
     return false;
 }
Пример #7
0
        private static void DisposeOutPts(OutPt pp)
        {
            Contract.Requires(pp == null || pp.Prev != null);

            if (pp == null)
                return;
            pp.Prev.Next = null;
            while (pp != null)
            {
                pp = pp.Next;
            }
        }
Пример #8
0
        private bool JoinPoints(JoinRec j, out OutPt p1, out OutPt p2)
        {
            Contract.Requires(j != null);
            Contract.Requires(j.Poly1Idx >= 0 && j.Poly1Idx < _polyOuts.Count);
            Contract.Requires(j.Poly2Idx >= 0 && j.Poly2Idx < _polyOuts.Count);

            p1 = null;
            p2 = null;
            var outRec1 = _polyOuts[j.Poly1Idx];
            var outRec2 = _polyOuts[j.Poly2Idx];
            if (outRec1 == null || outRec2 == null)
                return false;
            var pp1A = outRec1.Pts;
            var pp2A = outRec2.Pts;
            IntPoint pt1 = j.Pt2A, pt2 = j.Pt2B;
            IntPoint pt3 = j.Pt1A, pt4 = j.Pt1B;
            if (!FindSegment(ref pp1A, ref pt1, ref pt2))
                return false;
            if (outRec1 == outRec2)
            {
                //we're searching the same polygon for overlapping segments so
                //segment 2 mustn't be the same as segment 1 ...
                pp2A = pp1A.Next;
                if (!FindSegment(ref pp2A, ref pt3, ref pt4) || (pp2A == pp1A))
                    return false;
            }
            else if (!FindSegment(ref pp2A, ref pt3, ref pt4))
                return false;

            if (!GetOverlapSegment(pt1, pt2, pt3, pt4, out pt1, out pt2))
                return false;

            OutPt p3, p4, prev = pp1A.Prev;
            //get p1 & p2 polypts - the overlap start & endpoints on poly1
            if (pp1A.Pt.Equals(pt1))
                p1 = pp1A;
            else if (prev.Pt.Equals(pt1))
                p1 = prev;
            else
                p1 = InsertPolyPtBetween(pp1A, prev, pt1);

            if (pp1A.Pt.Equals(pt2))
                p2 = pp1A;
            else if (prev.Pt.Equals(pt2))
                p2 = prev;
            else if ((p1 == pp1A) || (p1 == prev))
                p2 = InsertPolyPtBetween(pp1A, prev, pt2);
            else if (Pt3IsBetweenPt1AndPt2(pp1A.Pt, p1.Pt, pt2))
                p2 = InsertPolyPtBetween(pp1A, p1, pt2);
            else
                p2 = InsertPolyPtBetween(p1, prev, pt2);

            //get p3 & p4 polypts - the overlap start & endpoints on poly2
            prev = pp2A.Prev;
            if (pp2A.Pt.Equals(pt1))
                p3 = pp2A;
            else if (prev.Pt.Equals(pt1))
                p3 = prev;
            else
                p3 = InsertPolyPtBetween(pp2A, prev, pt1);

            if (pp2A.Pt.Equals(pt2))
                p4 = pp2A;
            else if (prev.Pt.Equals(pt2))
                p4 = prev;
            else if ((p3 == pp2A) || (p3 == prev))
                p4 = InsertPolyPtBetween(pp2A, prev, pt2);
            else if (Pt3IsBetweenPt1AndPt2(pp2A.Pt, p3.Pt, pt2))
                p4 = InsertPolyPtBetween(pp2A, p3, pt2);
            else
                p4 = InsertPolyPtBetween(p3, prev, pt2);

            //p1.pt == p3.pt and p2.pt == p4.pt so join p1 to p3 and p2 to p4 ...
            if (p1.Next == p2 && p3.Prev == p4)
            {
                p1.Next = p3;
                p3.Prev = p1;
                p2.Prev = p4;
                p4.Next = p2;
                return true;
            }
            else if (p1.Prev == p2 && p3.Next == p4)
            {
                p1.Prev = p3;
                p3.Next = p1;
                p2.Next = p4;
                p4.Prev = p2;
                return true;
            }
            else
                return false; //an orientation is probably wrong
        }
Пример #9
0
 private void FixupJoinRecs(JoinRec j, OutPt pt, int startIdx)
 {
     for (var k = startIdx; k < _joins.Count; k++)
     {
         var j2 = _joins[k];
         if (j2.Poly1Idx == j.Poly1Idx && InternalHelpers.PointIsVertex(j2.Pt1A, pt))
             j2.Poly1Idx = j.Poly2Idx;
         if (j2.Poly2Idx == j.Poly1Idx && InternalHelpers.PointIsVertex(j2.Pt2A, pt))
             j2.Poly2Idx = j.Poly2Idx;
     }
 }