예제 #1
0
        //------------------------------------------------------------------------------

        internal bool PointInPolygon(IntPoint pt, OutPt pp, bool UseFulllongRange)
        {
            OutPt pp2 = pp;
            bool result = false;
            if (UseFulllongRange)
            {
                do
                {
                    if ((((pp2.pt.Y <= pt.Y) && (pt.Y < pp2.prev.pt.Y)) ||
                        ((pp2.prev.pt.Y <= pt.Y) && (pt.Y < pp2.pt.Y))) &&
                        new Int128(pt.X - pp2.pt.X) <
                        Int128.Int128Mul(pp2.prev.pt.X - pp2.pt.X, pt.Y - pp2.pt.Y) /
                        new Int128(pp2.prev.pt.Y - pp2.pt.Y))
                        result = !result;
                    pp2 = pp2.next;
                }
                while (pp2 != pp);
            }
            else
            {
                do
                {
                    if ((((pp2.pt.Y <= pt.Y) && (pt.Y < pp2.prev.pt.Y)) ||
                      ((pp2.prev.pt.Y <= pt.Y) && (pt.Y < pp2.pt.Y))) &&
                      (pt.X - pp2.pt.X < (pp2.prev.pt.X - pp2.pt.X) * (pt.Y - pp2.pt.Y) /
                      (pp2.prev.pt.Y - pp2.pt.Y))) result = !result;
                    pp2 = pp2.next;
                }
                while (pp2 != pp);
            }
            return result;
        }
예제 #2
0
        //------------------------------------------------------------------------------

        internal bool PointIsVertex(IntPoint pt, OutPt pp)
        {
            OutPt pp2 = pp;
            do
            {
                if (PointsEqual(pp2.pt, pt)) return true;
                pp2 = pp2.next;
            }
            while (pp2 != pp);
            return false;
        }
예제 #3
0
        //------------------------------------------------------------------------------

        internal bool PointOnPolygon(IntPoint pt, OutPt pp, bool UseFullInt64Range)
        {
            OutPt pp2 = pp;
            while (true)
            {
                if (PointOnLineSegment(pt, pp2.pt, pp2.next.pt, UseFullInt64Range))
                    return true;
                pp2 = pp2.next;
                if (pp2 == pp) break;
            }
            return false;
        }
예제 #4
0
        //----------------------------------------------------------------------

        private void FixupJoinRecs(JoinRec j, OutPt pt, int startIdx)
        {
            for (int k = startIdx; k < m_Joins.Count; k++)
            {
                JoinRec j2 = m_Joins[k];
                if (j2.poly1Idx == j.poly1Idx && PointIsVertex(j2.pt1a, pt))
                    j2.poly1Idx = j.poly2Idx;
                if (j2.poly2Idx == j.poly1Idx && PointIsVertex(j2.pt2a, pt))
                    j2.poly2Idx = j.poly2Idx;
            }
        }
예제 #5
0
        //----------------------------------------------------------------------

        private bool Poly2ContainsPoly1(OutPt outPt1, OutPt outPt2, bool UseFullInt64Range)
        {
            OutPt pt = outPt1;
            //Because the polygons may be touching, we need to find a vertex that
            //isn't touching the other polygon ...
            if (PointOnPolygon(pt.pt, outPt2, UseFullInt64Range))
            {
                pt = pt.next;
                while (pt != outPt1 && PointOnPolygon(pt.pt, outPt2, UseFullInt64Range))
                    pt = pt.next;
                if (pt == outPt1) return true;
            }
            return PointInPolygon(pt.pt, outPt2, UseFullInt64Range);
        }
예제 #6
0
        //------------------------------------------------------------------------------

        private int PointCount(OutPt pts)
        {
            if (pts == null) return 0;
            int result = 0;
            OutPt p = pts;
            do
            {
                result++;
                p = p.next;
            }
            while (p != pts);
            return result;
        }
예제 #7
0
        //------------------------------------------------------------------------------

        private bool JoinPoints(JoinRec j, out OutPt p1, out OutPt p2)
        {
            p1 = null; p2 = null;
            OutRec outRec1 = m_PolyOuts[j.poly1Idx];
            OutRec outRec2 = m_PolyOuts[j.poly2Idx];
            if (outRec1 == null || outRec2 == null) return false;
            OutPt pp1a = outRec1.pts;
            OutPt pp2a = outRec2.pts;
            IntPoint pt1 = j.pt2a, pt2 = j.pt2b;
            IntPoint pt3 = j.pt1a, pt4 = j.pt1b;
            if (!FindSegment(ref pp1a, m_UseFullRange, 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, m_UseFullRange, ref pt3, ref pt4) || (pp2a == pp1a))
                    return false;
            }
            else if (!FindSegment(ref pp2a, m_UseFullRange, ref pt3, ref pt4)) return false;

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

            OutPt p3, p4, prev = pp1a.prev;
            //get p1 & p2 polypts - the overlap start & endpoints on poly1
            if (PointsEqual(pp1a.pt, pt1)) p1 = pp1a;
            else if (PointsEqual(prev.pt, pt1)) p1 = prev;
            else p1 = InsertPolyPtBetween(pp1a, prev, pt1);

            if (PointsEqual(pp1a.pt, pt2)) p2 = pp1a;
            else if (PointsEqual(prev.pt, 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 (PointsEqual(pp2a.pt, pt1)) p3 = pp2a;
            else if (PointsEqual(prev.pt, pt1)) p3 = prev;
            else p3 = InsertPolyPtBetween(pp2a, prev, pt1);

            if (PointsEqual(pp2a.pt, pt2)) p4 = pp2a;
            else if (PointsEqual(prev.pt, 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
        }
예제 #8
0
        //------------------------------------------------------------------------------

        private OutPt GetBottomPt(OutPt pp)
        {
            OutPt dups = null;
            OutPt p = pp.next;
            while (p != pp)
            {
                if (p.pt.Y > pp.pt.Y)
                {
                    pp = p;
                    dups = null;
                }
                else if (p.pt.Y == pp.pt.Y && p.pt.X <= pp.pt.X)
                {
                    if (p.pt.X < pp.pt.X)
                    {
                        dups = null;
                        pp = p;
                    }
                    else
                    {
                        if (p.next != pp && p.prev != pp) dups = p;
                    }
                }
                p = p.next;
            }
            if (dups != null)
            {
                //there appears to be at least 2 vertices at bottomPt so ...
                while (dups != p)
                {
                    if (!FirstIsBottomPt(p, dups)) pp = dups;
                    dups = dups.next;
                    while (!PointsEqual(dups.pt, pp.pt)) dups = dups.next;
                }
            }
            return pp;
        }
예제 #9
0
        //------------------------------------------------------------------------------

        private void ReversePolyPtLinks(OutPt pp)
        {
            if (pp == null) return;
            OutPt pp1;
            OutPt pp2;
            pp1 = pp;
            do
            {
                pp2 = pp1.next;
                pp1.next = pp1.prev;
                pp1.prev = pp2;
                pp1 = pp2;
            } while (pp1 != pp);
        }
예제 #10
0
        //---------------------------------------------------------------------------

        private bool FirstIsBottomPt(OutPt btmPt1, OutPt btmPt2)
        {
            OutPt p = btmPt1.prev;
            while (PointsEqual(p.pt, btmPt1.pt) && (p != btmPt1)) p = p.prev;
            double dx1p = Math.Abs(GetDx(btmPt1.pt, p.pt));
            p = btmPt1.next;
            while (PointsEqual(p.pt, btmPt1.pt) && (p != btmPt1)) p = p.next;
            double dx1n = Math.Abs(GetDx(btmPt1.pt, p.pt));

            p = btmPt2.prev;
            while (PointsEqual(p.pt, btmPt2.pt) && (p != btmPt2)) p = p.prev;
            double dx2p = Math.Abs(GetDx(btmPt2.pt, p.pt));
            p = btmPt2.next;
            while (PointsEqual(p.pt, btmPt2.pt) && (p != btmPt2)) p = p.next;
            double dx2n = Math.Abs(GetDx(btmPt2.pt, p.pt));
            return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
        }
예제 #11
0
        //------------------------------------------------------------------------------

        private OutPt InsertPolyPtBetween(OutPt p1, OutPt p2, IntPoint pt)
        {
            OutPt result = new OutPt();
            result.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;
        }
예제 #12
0
        //------------------------------------------------------------------------------

        private bool FindSegment(ref OutPt pp, bool UseFullInt64Range,
            ref IntPoint pt1, ref IntPoint pt2)
        {
            if (pp == null) return false;
            OutPt pp2 = pp;
            IntPoint pt1a = new IntPoint(pt1);
            IntPoint pt2a = new IntPoint(pt2);
            do
            {
                if (SlopesEqual(pt1a, pt2a, pp.pt, pp.prev.pt, UseFullInt64Range) &&
                    SlopesEqual(pt1a, pt2a, pp.pt, UseFullInt64Range) &&
                    GetOverlapSegment(pt1a, pt2a, pp.pt, pp.prev.pt, ref pt1, ref pt2))
                    return true;
                pp = pp.next;
            }
            while (pp != pp2);
            return false;
        }
예제 #13
0
        //------------------------------------------------------------------------------

        private void AddOutPt(TEdge e, IntPoint pt)
        {
            bool ToFront = (e.side == EdgeSide.esLeft);
            if (e.outIdx < 0)
            {
                OutRec outRec = CreateOutRec();
                e.outIdx = outRec.idx;
                OutPt op = new OutPt();
                outRec.pts = op;
                op.pt = pt;
                op.idx = outRec.idx;
                op.next = op;
                op.prev = op;
                SetHoleState(e, outRec);
            }
            else
            {
                OutRec outRec = m_PolyOuts[e.outIdx];
                OutPt op = outRec.pts, op2;
                if (ToFront && PointsEqual(pt, op.pt) ||
                    (!ToFront && PointsEqual(pt, op.prev.pt))) return;

                op2 = new OutPt();
                op2.pt = pt;
                op2.idx = outRec.idx;
                op2.next = op;
                op2.prev = op.prev;
                op2.prev.next = op2;
                op.prev = op2;
                if (ToFront) outRec.pts = op2;
            }
        }
예제 #14
0
        //------------------------------------------------------------------------------

        private void DisposeOutPts(OutPt pp)
        {
            if (pp == null) return;
            OutPt tmpPp = null;
            pp.prev.next = null;
            while (pp != null)
            {
                tmpPp = pp;
                pp = pp.next;
                tmpPp = null;
            }
        }