//------------------------------------------------------------------------------
 internal int PolySort(OutRec or1, OutRec or2)
 {
     if (or1 == or2) return 0;
       else if (or1.pts == null || or2.pts == null)
       {
     if ((or1.pts == null) != (or2.pts == null))
     {
         if (or1.pts != null) return -1; else return 1;
     }
     else return 0;
       }
       int i1, i2;
       if (or1.isHole)
     i1 = or1.FirstLeft.idx; else
     i1 = or1.idx;
       if (or2.isHole)
     i2 = or2.FirstLeft.idx; else
     i2 = or2.idx;
       int result = i1 - i2;
       if (result == 0 && (or1.isHole != or2.isHole))
       {
       if (or1.isHole) return 1;
       else return -1;
       }
       return result;
 }
 //----------------------------------------------------------------------
 private void CheckHoleLinkages2(OutRec outRec1, OutRec outRec2)
 {
     //if a hole is owned by outRec2 then make it owned by outRec1 ...
       for (int i = 0; i < m_PolyOuts.Count; ++i)
     if (m_PolyOuts[i].isHole && m_PolyOuts[i].bottomPt != null &&
       m_PolyOuts[i].FirstLeft == outRec2)
         m_PolyOuts[i].FirstLeft = outRec1;
 }
        //------------------------------------------------------------------------------
        private bool Orientation(OutRec outRec, bool UseFull64BitRange)
        {
            OutPt opBottom = outRec.pts, op = outRec.pts.next;
            while (op != outRec.pts)
            {
                if (op.pt.Y >= opBottom.pt.Y)
                {
                    if (op.pt.Y > opBottom.pt.Y || op.pt.X < opBottom.pt.X)
                    opBottom = op;
                }
                op = op.next;
            }

            IntPoint vec1 = new IntPoint(op.pt.X - op.prev.pt.X, op.pt.Y - op.prev.pt.Y);
            IntPoint vec2 = new IntPoint(op.next.pt.X - op.pt.X, op.next.pt.Y - op.pt.Y);

            if (UseFull64BitRange)
            {
                Int128 cross = Int128.Int128Mul(vec1.X, vec2.Y) - Int128.Int128Mul(vec2.X, vec1.Y);
                return !cross.IsNegative();
            }
            else
            {
                return (vec1.X * vec2.Y - vec2.X * vec1.Y) > 0;
            }
        }
 //------------------------------------------------------------------------------
 internal OutRec FindAppendLinkEnd(OutRec outRec)
 {
     while (outRec.AppendLink != null) outRec = outRec.AppendLink;
       return outRec;
 }
Пример #5
0
        //----------------------------------------------------------------------

        private void FixupFirstLefts2(OutRec OldOutRec, OutRec NewOutRec)
        { 
            foreach (OutRec outRec in m_PolyOuts)
                if (outRec.FirstLeft == OldOutRec) outRec.FirstLeft = NewOutRec;
        }
 //------------------------------------------------------------------------------
 private void FixupOutPolygon(OutRec outRec)
 {
     //FixupOutPolygon() - removes duplicate points and simplifies consecutive
     //parallel edges by removing the middle vertex.
     OutPt lastOK = null;
     outRec.pts = outRec.bottomPt;
     OutPt pp = outRec.bottomPt;
     for (;;)
     {
         if (pp.prev == pp || pp.prev == pp.next)
         {
             DisposeOutPts(pp);
             outRec.pts = null;
             outRec.bottomPt = null;
             return;
         }
         //test for duplicate points and for same slope (cross-product) ...
         if (PointsEqual(pp.pt, pp.next.pt) ||
           SlopesEqual(pp.prev.pt, pp.pt, pp.next.pt, m_UseFullRange))
         {
             lastOK = null;
             OutPt tmp = pp;
             if (pp == outRec.bottomPt)
             {
                 if (tmp.prev.pt.Y > tmp.next.pt.Y)
                   outRec.bottomPt = tmp.prev; else
                   outRec.bottomPt = tmp.next;
                 outRec.pts = outRec.bottomPt;
                 outRec.bottomPt.idx = outRec.idx;
             }
             pp.prev.next = pp.next;
             pp.next.prev = pp.prev;
             pp = pp.prev;
             tmp = null;
         }
         else if (pp == lastOK) break;
         else
         {
             if (lastOK == null) lastOK = pp;
             pp = pp.next;
         }
     }
 }
Пример #7
0
      //------------------------------------------------------------------------------

      private OutRec CreateOutRec()
      {
        OutRec result = new OutRec();
        result.Idx = Unassigned;
        result.IsHole = false;
        result.IsOpen = false;
        result.FirstLeft = null;
        result.Pts = null;
        result.BottomPt = null;
        result.PolyNode = null;
        m_PolyOuts.Add(result);
        result.Idx = m_PolyOuts.Count - 1;
        return result;
      }
Пример #8
0
        //------------------------------------------------------------------------------

        bool Param1RightOfParam2(OutRec outRec1, OutRec outRec2)
        {
            do
            {
                outRec1 = outRec1.FirstLeft;
                if (outRec1 == outRec2) return true;
            } while (outRec1 != null);
            return false;
        }
Пример #9
0
 //------------------------------------------------------------------------------
 private OutRec CreateOutRec()
 {
     OutRec result = new OutRec();
       result.idx = -1;
       result.isHole = false;
       result.FirstLeft = null;
       result.AppendLink = null;
       result.pts = null;
       result.bottomPt = null;
       result.bottomFlag = null;
       result.sides = EdgeSide.esNeither;
       return result;
 }
Пример #10
0
 //------------------------------------------------------------------------------
 void DisposeBottomPt(OutRec outRec)
 {
     OutPt next = outRec.bottomPt.next;
       OutPt prev = outRec.bottomPt.prev;
       if (outRec.pts == outRec.bottomPt) outRec.pts = next;
       outRec.bottomPt = null;
       next.prev = prev;
       prev.next = next;
       outRec.bottomPt = next;
       FixupOutPolygon(outRec);
 }
Пример #11
0
 //----------------------------------------------------------------------
 private static OutRec ParseFirstLeft(OutRec FirstLeft)
 {
     while (FirstLeft != null && FirstLeft.Pts == null)
         FirstLeft = FirstLeft.FirstLeft;
     return FirstLeft;
 }
Пример #12
0
 //------------------------------------------------------------------------------
 internal double Area(OutRec outRec)
 {
     return Area(outRec.Pts);
 }
Пример #13
0
        //------------------------------------------------------------------------------
        private void SetHoleState(TEdge e, OutRec outRec)
        {
            TEdge e2 = e.PrevInAEL;
            TEdge eTmp = null;
            while (e2 != null)
            {
                if (e2.OutIdx >= 0 && e2.WindDelta != 0)
                {
                    if (eTmp == null)
                        eTmp = e2;
                    else if (eTmp.OutIdx == e2.OutIdx)
                        eTmp = null; //paired
                }
                e2 = e2.PrevInAEL;
            }

            if (eTmp == null)
            {
                outRec.FirstLeft = null;
                outRec.IsHole = false;
            }
            else
            {
                outRec.FirstLeft = m_PolyOuts[eTmp.OutIdx];
                outRec.IsHole = !outRec.FirstLeft.IsHole;
            }
        }
Пример #14
0
        //------------------------------------------------------------------------------
        private bool JoinPoints(Join j, OutRec outRec1, OutRec outRec2)
        {
            OutPt op1 = j.OutPt1, op1b;
            OutPt op2 = j.OutPt2, op2b;

            //There are 3 kinds of joins for output polygons ...
            //1. Horizontal joins where Join.OutPt1 & Join.OutPt2 are vertices anywhere
            //along (horizontal) collinear edges (& Join.OffPt is on the same horizontal).
            //2. Non-horizontal joins where Join.OutPt1 & Join.OutPt2 are at the same
            //location at the Bottom of the overlapping segment (& Join.OffPt is above).
            //3. StrictlySimple joins where edges touch but are not collinear and where
            //Join.OutPt1, Join.OutPt2 & Join.OffPt all share the same point.
            bool isHorizontal = (j.OutPt1.Pt.Y == j.OffPt.Y);

            if (isHorizontal && (j.OffPt == j.OutPt1.Pt) && (j.OffPt == j.OutPt2.Pt))
            {
                //Strictly Simple join ...
                if (outRec1 != outRec2) return false;
                op1b = j.OutPt1.Next;
                while (op1b != op1 && (op1b.Pt == j.OffPt))
                    op1b = op1b.Next;
                bool reverse1 = (op1b.Pt.Y > j.OffPt.Y);
                op2b = j.OutPt2.Next;
                while (op2b != op2 && (op2b.Pt == j.OffPt))
                    op2b = op2b.Next;
                bool reverse2 = (op2b.Pt.Y > j.OffPt.Y);
                if (reverse1 == reverse2) return false;
                if (reverse1)
                {
                    op1b = DupOutPt(op1, false);
                    op2b = DupOutPt(op2, true);
                    op1.Prev = op2;
                    op2.Next = op1;
                    op1b.Next = op2b;
                    op2b.Prev = op1b;
                    j.OutPt1 = op1;
                    j.OutPt2 = op1b;
                    return true;
                }
                else
                {
                    op1b = DupOutPt(op1, true);
                    op2b = DupOutPt(op2, false);
                    op1.Next = op2;
                    op2.Prev = op1;
                    op1b.Prev = op2b;
                    op2b.Next = op1b;
                    j.OutPt1 = op1;
                    j.OutPt2 = op1b;
                    return true;
                }
            }
            else if (isHorizontal)
            {
                //treat horizontal joins differently to non-horizontal joins since with
                //them we're not yet sure where the overlapping is. OutPt1.Pt & OutPt2.Pt
                //may be anywhere along the horizontal edge.
                op1b = op1;
                while (op1.Prev.Pt.Y == op1.Pt.Y && op1.Prev != op1b && op1.Prev != op2)
                    op1 = op1.Prev;
                while (op1b.Next.Pt.Y == op1b.Pt.Y && op1b.Next != op1 && op1b.Next != op2)
                    op1b = op1b.Next;
                if (op1b.Next == op1 || op1b.Next == op2) return false; //a flat 'polygon'

                op2b = op2;
                while (op2.Prev.Pt.Y == op2.Pt.Y && op2.Prev != op2b && op2.Prev != op1b)
                    op2 = op2.Prev;
                while (op2b.Next.Pt.Y == op2b.Pt.Y && op2b.Next != op2 && op2b.Next != op1)
                    op2b = op2b.Next;
                if (op2b.Next == op2 || op2b.Next == op1) return false; //a flat 'polygon'

                int Left, Right;
                //Op1 -. Op1b & Op2 -. Op2b are the extremites of the horizontal edges
                if (!GetOverlap(op1.Pt.X, op1b.Pt.X, op2.Pt.X, op2b.Pt.X, out Left, out Right))
                    return false;

                //DiscardLeftSide: when overlapping edges are joined, a spike will created
                //which needs to be cleaned up. However, we don't want Op1 or Op2 caught up
                //on the discard Side as either may still be needed for other joins ...
                IntPoint Pt;
                bool DiscardLeftSide;
                if (op1.Pt.X >= Left && op1.Pt.X <= Right)
                {
                    Pt = op1.Pt; DiscardLeftSide = (op1.Pt.X > op1b.Pt.X);
                }
                else if (op2.Pt.X >= Left && op2.Pt.X <= Right)
                {
                    Pt = op2.Pt; DiscardLeftSide = (op2.Pt.X > op2b.Pt.X);
                }
                else if (op1b.Pt.X >= Left && op1b.Pt.X <= Right)
                {
                    Pt = op1b.Pt; DiscardLeftSide = op1b.Pt.X > op1.Pt.X;
                }
                else
                {
                    Pt = op2b.Pt; DiscardLeftSide = (op2b.Pt.X > op2.Pt.X);
                }
                j.OutPt1 = op1;
                j.OutPt2 = op2;
                return JoinHorz(op1, op1b, op2, op2b, Pt, DiscardLeftSide);
            }
            else
            {
                //nb: For non-horizontal joins ...
                //    1. Jr.OutPt1.Pt.Y == Jr.OutPt2.Pt.Y
                //    2. Jr.OutPt1.Pt > Jr.OffPt.Y

                //make sure the polygons are correctly oriented ...
                op1b = op1.Next;
                while ((op1b.Pt == op1.Pt) && (op1b != op1)) op1b = op1b.Next;
                bool Reverse1 = ((op1b.Pt.Y > op1.Pt.Y) ||
                  !SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, m_UseFullRange));
                if (Reverse1)
                {
                    op1b = op1.Prev;
                    while ((op1b.Pt == op1.Pt) && (op1b != op1)) op1b = op1b.Prev;
                    if ((op1b.Pt.Y > op1.Pt.Y) ||
                      !SlopesEqual(op1.Pt, op1b.Pt, j.OffPt, m_UseFullRange)) return false;
                };
                op2b = op2.Next;
                while ((op2b.Pt == op2.Pt) && (op2b != op2)) op2b = op2b.Next;
                bool Reverse2 = ((op2b.Pt.Y > op2.Pt.Y) ||
                  !SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, m_UseFullRange));
                if (Reverse2)
                {
                    op2b = op2.Prev;
                    while ((op2b.Pt == op2.Pt) && (op2b != op2)) op2b = op2b.Prev;
                    if ((op2b.Pt.Y > op2.Pt.Y) ||
                      !SlopesEqual(op2.Pt, op2b.Pt, j.OffPt, m_UseFullRange)) return false;
                }

                if ((op1b == op1) || (op2b == op2) || (op1b == op2b) ||
                  ((outRec1 == outRec2) && (Reverse1 == Reverse2))) return false;

                if (Reverse1)
                {
                    op1b = DupOutPt(op1, false);
                    op2b = DupOutPt(op2, true);
                    op1.Prev = op2;
                    op2.Next = op1;
                    op1b.Next = op2b;
                    op2b.Prev = op1b;
                    j.OutPt1 = op1;
                    j.OutPt2 = op1b;
                    return true;
                }
                else
                {
                    op1b = DupOutPt(op1, true);
                    op2b = DupOutPt(op2, false);
                    op1.Next = op2;
                    op2.Prev = op1;
                    op1b.Prev = op2b;
                    op2b.Next = op1b;
                    j.OutPt1 = op1;
                    j.OutPt2 = op1b;
                    return true;
                }
            }
        }
Пример #15
0
      //------------------------------------------------------------------------------

      private OutRec GetLowermostRec(OutRec outRec1, OutRec outRec2)
      {
          //work out which polygon fragment has the correct hole state ...
          if (outRec1.BottomPt == null) 
              outRec1.BottomPt = GetBottomPt(outRec1.Pts);
          if (outRec2.BottomPt == null) 
              outRec2.BottomPt = GetBottomPt(outRec2.Pts);
          OutPt bPt1 = outRec1.BottomPt;
          OutPt bPt2 = outRec2.BottomPt;
          if (bPt1.Pt.Y > bPt2.Pt.Y) return outRec1;
          else if (bPt1.Pt.Y < bPt2.Pt.Y) return outRec2;
          else if (bPt1.Pt.X < bPt2.Pt.X) return outRec1;
          else if (bPt1.Pt.X > bPt2.Pt.X) return outRec2;
          else if (bPt1.Next == bPt1) return outRec2;
          else if (bPt2.Next == bPt2) return outRec1;
          else if (FirstIsBottomPt(bPt1, bPt2)) return outRec1;
          else return outRec2;
      }
Пример #16
0
        //------------------------------------------------------------------------------

        private OutRec GetLowermostRec(OutRec outRec1, OutRec outRec2)
        {
            //work out which polygon fragment has the correct hole state ...
            OutPt bPt1 = outRec1.bottomPt;
            OutPt bPt2 = outRec2.bottomPt;
            if (bPt1.pt.Y > bPt2.pt.Y) return outRec1;
            else if (bPt1.pt.Y < bPt2.pt.Y) return outRec2;
            else if (bPt1.pt.X < bPt2.pt.X) return outRec1;
            else if (bPt1.pt.X > bPt2.pt.X) return outRec2;
            else if (bPt1.next == bPt1) return outRec2;
            else if (bPt2.next == bPt2) return outRec1;
            else if (FirstIsBottomPt(bPt1, bPt2)) return outRec1;
            else return outRec2;
        }
Пример #17
0
      //------------------------------------------------------------------------------

      private void FixupOutPolygon(OutRec outRec)
      {
          //FixupOutPolygon() - removes duplicate points and simplifies consecutive
          //parallel edges by removing the middle vertex.
          OutPt lastOK = null;
          outRec.BottomPt = null;
          OutPt pp = outRec.Pts;
          for (;;)
          {
              if (pp.Prev == pp || pp.Prev == pp.Next)
              {
                  DisposeOutPts(pp);
                  outRec.Pts = null;
                  return;
              }
              //test for duplicate points and collinear edges ...
              if ((pp.Pt == pp.Next.Pt) || (pp.Pt == pp.Prev.Pt) ||
                (SlopesEqual(pp.Prev.Pt, pp.Pt, pp.Next.Pt, m_UseFullRange) &&
                (!PreserveCollinear || !Pt2IsBetweenPt1AndPt3(pp.Prev.Pt, pp.Pt, pp.Next.Pt))))
              {
                  lastOK = null;
                  OutPt tmp = pp;
                  pp.Prev.Next = pp.Next;
                  pp.Next.Prev = pp.Prev;
                  pp = pp.Prev;
                  tmp = null;
              }
              else if (pp == lastOK) break;
              else
              {
                  if (lastOK == null) lastOK = pp;
                  pp = pp.Next;
              }
          }
          outRec.Pts = pp;
      }
Пример #18
0
        //----------------------------------------------------------------------

        private void FixupFirstLefts1(OutRec OldOutRec, OutRec NewOutRec)
        { 
            for (int i = 0; i < m_PolyOuts.Count; i++)
            {
                OutRec outRec = m_PolyOuts[i];
                if (outRec.pts != null && outRec.FirstLeft == OldOutRec) 
                {
                    if (Poly2ContainsPoly1(outRec.pts, NewOutRec.pts, m_UseFullRange))
                        outRec.FirstLeft = NewOutRec;
                }
            }
        }
Пример #19
0
      //------------------------------------------------------------------------------

      private void UpdateOutPtIdxs(OutRec outrec)
      {  
        OutPt op = outrec.Pts;
        do
        {
          op.Idx = outrec.Idx;
          op = op.Prev;
        }
        while(op != outrec.Pts);
      }
Пример #20
0
        //------------------------------------------------------------------------------

        double Area(OutRec outRec, bool UseFull64BitRange)
        {
          OutPt op = outRec.pts;
          if (op == null) return 0;
          if (UseFull64BitRange) 
          {
            Int128 a = new Int128(0);
            do
            {
                a += Int128.Int128Mul(op.pt.X + op.prev.pt.X, op.prev.pt.Y - op.pt.Y);
                op = op.next;
            } while (op != outRec.pts);
            return a.ToDouble() / 2;          
          }
          else
          {
            double a = 0;
            do {
                a = a + (op.pt.X + op.prev.pt.X) * (op.prev.pt.Y - op.pt.Y);
              op = op.next;
            } while (op != outRec.pts);
            return a/2;
          }
        }
Пример #21
0
      //------------------------------------------------------------------------------

      double Area(OutRec outRec)
      {
        OutPt op = outRec.Pts;
        if (op == null) return 0;
        double a = 0;
        do {
          a = a + (double)(op.Pt.X + op.Prev.Pt.X) * (double)(op.Prev.Pt.Y - op.Pt.Y);
          op = op.Next;
        } while (op != outRec.Pts);
        return a/2;
      }
 //---------------------------------------------------------------------------
 private OutRec GetLowermostRec(OutRec outRec1, OutRec outRec2)
 {
     //work out which polygon fragment has the correct hole state ...
     OutPt bPt1 = outRec1.bottomPt;
     OutPt bPt2 = outRec2.bottomPt;
     if (bPt1.pt.Y > bPt2.pt.Y) return outRec1;
     else if (bPt1.pt.Y < bPt2.pt.Y) return outRec2;
     else if (bPt1.pt.X < bPt2.pt.X) return outRec1;
     else if (bPt1.pt.X > bPt2.pt.X) return outRec2;
     else if (outRec1.bottomE2 == null) return outRec2;
     else if (outRec2.bottomE2 == null) return outRec1;
     else
     {
         Int64 y1 = Math.Max(outRec1.bottomE1.ybot, outRec1.bottomE2.ybot);
         Int64 y2 = Math.Max(outRec2.bottomE1.ybot, outRec2.bottomE2.ybot);
         if (y2 == y1 || (y1 > bPt1.pt.Y && y2 > bPt1.pt.Y))
         {
           double dx1 = Math.Max(outRec1.bottomE1.dx, outRec1.bottomE2.dx);
           double dx2 = Math.Max(outRec2.bottomE1.dx, outRec2.bottomE2.dx);
           if (dx2 > dx1) return outRec2; else return outRec1;
         }
         else if (y2 > y1) return outRec2;
         else return outRec1;
     }
 }
Пример #23
0
        //------------------------------------------------------------------------------
        private bool Orientation(OutRec outRec, bool UseFull64BitRange)
        {
            //first make sure bottomPt is correctly assigned ...
            OutPt opBottom = outRec.pts, op = outRec.pts.next;
            while (op != outRec.pts)
            {
                if (op.pt.Y >= opBottom.pt.Y)
                {
                    if (op.pt.Y > opBottom.pt.Y || op.pt.X < opBottom.pt.X)
                        opBottom = op;
                }
                op = op.next;
            }
            outRec.bottomPt = opBottom;

            //find vertices either side of bottomPt (skipping duplicate points) ....
            OutPt opPrev = op.prev;
            OutPt opNext = op.next;
            while (op != opPrev && PointsEqual(op.pt, opPrev.pt))
                opPrev = opPrev.prev;
            while (op != opNext && PointsEqual(op.pt, opNext.pt))
                opNext = opNext.next;

            IntPoint vec1 = new IntPoint(op.pt.X - opPrev.pt.X, op.pt.Y - opPrev.pt.Y);
            IntPoint vec2 = new IntPoint(opNext.pt.X - op.pt.X, opNext.pt.Y - op.pt.Y);

            if (UseFull64BitRange)
            {
                Int128 cross = Int128.Int128Mul(vec1.X, vec2.Y) - Int128.Int128Mul(vec2.X, vec1.Y);
                return !cross.IsNegative();
            }
            else
            {
                return (vec1.X * vec2.Y - vec2.X * vec1.Y) > 0;
            }
        }
 //------------------------------------------------------------------------------
 private void SetHoleState(TEdge e, OutRec outRec)
 {
     bool isHole = false;
     TEdge e2 = e.prevInAEL;
     while (e2 != null)
     {
         if (e2.outIdx >= 0)
         {
             isHole = !isHole;
             if (outRec.FirstLeft == null)
                 outRec.FirstLeft = m_PolyOuts[e2.outIdx];
         }
         e2 = e2.prevInAEL;
     }
     if (isHole) outRec.isHole = true;
 }
Пример #25
0
 //------------------------------------------------------------------------------
 private OutRec CreateOutRec()
 {
     OutRec result = new OutRec();
     result.idx = -1;
     result.isHole = false;
     result.FirstLeft = null;
     result.pts = null;
     result.bottomPt = null;
     result.polyNode = null;
     m_PolyOuts.Add(result);
     result.idx = m_PolyOuts.Count - 1;
     return result;
 }
        //------------------------------------------------------------------------------
        internal void FixHoleLinkage(OutRec outRec)
        {
            OutRec tmp;
            if (outRec.bottomPt != null)
                tmp = m_PolyOuts[outRec.bottomPt.idx].FirstLeft;
            else
                tmp = outRec.FirstLeft;
            if (outRec == tmp) throw new ClipperException("HoleLinkage error");

            if (tmp != null)
            {
                if (tmp.AppendLink != null) tmp = FindAppendLinkEnd(tmp);
                if (tmp == outRec) tmp = null;
                else if (tmp.isHole)
                {
                    FixHoleLinkage(tmp);
                    tmp = tmp.FirstLeft;
                }
            }
            outRec.FirstLeft = tmp;
            if (tmp == null) outRec.isHole = false;
            outRec.AppendLink = null;
        }
Пример #27
0
 //------------------------------------------------------------------------------
 private void UpdateOutPtIdxs(OutRec outrec)
 {
     OutPt op = outrec.pts;
     do
     {
         op.idx = outrec.idx;
         op = op.prev;
     }
     while (op != outrec.pts);
 }
 //------------------------------------------------------------------------------
 private void CheckHoleLinkages1(OutRec outRec1, OutRec outRec2)
 {
     //when a polygon is split into 2 polygons, make sure any holes the original
       //polygon contained link to the correct polygon ...
       for (int i = 0; i < m_PolyOuts.Count; ++i)
       {
     if (m_PolyOuts[i].isHole && m_PolyOuts[i].bottomPt != null &&
         m_PolyOuts[i].FirstLeft == outRec1 &&
         !PointInPolygon(m_PolyOuts[i].bottomPt.pt,
         outRec1.pts, m_UseFullRange))
             m_PolyOuts[i].FirstLeft = outRec2;
       }
 }
Пример #29
0
        //------------------------------------------------------------------------------

        internal void FixHoleLinkage(OutRec outRec)
        {
            //skip if an outermost polygon or
            //already already points to the correct FirstLeft ...
            if (outRec.FirstLeft == null ||                
                  (outRec.isHole != outRec.FirstLeft.isHole &&
                  outRec.FirstLeft.pts != null)) return;

            OutRec orfl = outRec.FirstLeft;
            while (orfl != null && ((orfl.isHole == outRec.isHole) || orfl.pts == null))
                orfl = orfl.FirstLeft;
            outRec.FirstLeft = orfl;
        }
 //------------------------------------------------------------------------------
 private OutRec CreateOutRec()
 {
     OutRec result = new OutRec();
       result.idx = -1;
       result.isHole = false;
       result.FirstLeft = null;
       result.AppendLink = null;
       result.pts = null;
       result.bottomPt = null;
       return result;
 }
Пример #31
0
        //------------------------------------------------------------------------------

        protected override void AddLocalMinPoly(Active e1, Active e2, Point pt)
        {
            base.AddLocalMinPoly(e1, e2, pt);

            OutRec locMinOr = e1.OutRec;

            (locMinOr.Pts as OutPtTri).outrec = locMinOr;
            UpdateHelper(locMinOr, locMinOr.Pts);
            if (locMinOr.Flag == OutrecFlag.Outer)
            {
                return;
            }

            //do 'keyholing' ...
            Active e = GetRightAdjacentHotEdge(e1);

            if (e == e2)
            {
                e = GetRightAdjacentHotEdge(e2);
            }
            if (e == null)
            {
                e = GetLeftAdjacentHotEdge(e1);
            }
            OutPt botLft = (e.OutRec as OutRecTri).leftOutpt;
            OutPt botRt  = GetOutPt(e);

            if (botLft == null || botRt.Pt.Y < botLft.Pt.Y)
            {
                botLft = botRt;
            }

            botRt = InsertPt(botLft.Pt, botLft.Prev);
            OutRec botOr = (botLft as OutPtTri).outrec;

            if (botOr.Pts == null)
            {
                botOr = botOr.Owner;
            }

            OutPt startOp = botOr.Pts;
            OutPt endOp   = startOp.Next;

            locMinOr.Flag  = OutrecFlag.Outer;
            locMinOr.Owner = null;
            OutPt locMinLft = locMinOr.Pts;
            OutPt locMinRt  = InsertPt(locMinLft.Pt, locMinLft);

            //locMinOr will contain the polygon to the right of the join (ascending),
            //and botOr will contain the polygon to the left of the join (descending).

            //tail . botRt . locMinRt : locMinRt is joined by botRt tail
            locMinRt.Next = endOp;
            endOp.Prev    = locMinRt;
            botRt.Next    = locMinRt;
            locMinRt.Prev = botRt;
            locMinOr.Pts  = locMinRt;

            //locMinLft . botLft . head : locMinLft joins behind botLft (left)
            startOp.Next   = locMinLft;
            locMinLft.Prev = startOp;
            botLft.Prev    = locMinLft;
            locMinLft.Next = botLft;
            (locMinLft as OutPtTri).outrec = botOr; //ie abreviated update()

            Update(locMinRt, locMinOr);             //updates the outrec for each op

            //exchange endE's ...
            e                    = botOr.EndE;
            botOr.EndE           = locMinOr.EndE;
            locMinOr.EndE        = e;
            botOr.EndE.OutRec    = botOr;
            locMinOr.EndE.OutRec = locMinOr;

            //update helper info  ...
            UpdateHelper(locMinOr, locMinRt);
            UpdateHelper(botOr, botOr.Pts);
            Triangulate(locMinOr);
            Triangulate(botOr);
        }