Beispiel #1
0
        //------------------------------------------------------------------------------

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

        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;
          }
        }
Beispiel #3
0
        //----------------------------------------------------------------------

        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;
        }
Beispiel #4
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;
            opBottom.idx = outRec.idx;
            
            op = 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;

        }
Beispiel #5
0
        //------------------------------------------------------------------------------

        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;
                    if (pp == outRec.bottomPt)
                         outRec.bottomPt = null; //flags need for updating
                    pp.prev.next = pp.next;
                    pp.next.prev = pp.prev;
                    pp = pp.prev;
                }
                else if (pp == lastOK) break;
                else
                {
                    if (lastOK == null) lastOK = pp;
                    pp = pp.next;
                }
            }
          if (outRec.bottomPt == null) 
          {
            outRec.bottomPt = GetBottomPt(pp);
            outRec.bottomPt.idx = outRec.idx;
            outRec.pts = outRec.bottomPt;
          }
        }
Beispiel #6
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;
        }
Beispiel #7
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;
        }
Beispiel #8
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;
        }
Beispiel #9
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;
        }
Beispiel #10
0
        //------------------------------------------------------------------------------

        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;
        }
Beispiel #11
0
        //------------------------------------------------------------------------------

        internal OutRec FindAppendLinkEnd(OutRec outRec)
        {
          while (outRec.AppendLink != null) outRec = outRec.AppendLink;
          return outRec;
        }
Beispiel #12
0
        //------------------------------------------------------------------------------

        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))
            {
                return or1.pts == null ? 1 : -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))
          {
              return or1.isHole ? 1 : -1;
          }
          return result;
        }