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

        private void InitEdge(ClipperTEdge e, ClipperTEdge eNext,
                              ClipperTEdge ePrev, ClipperIntPoint pt)
        {
            e.Next   = eNext;
            e.Prev   = ePrev;
            e.Curr   = pt;
            e.OutIdx = Unassigned;
        }
예제 #2
0
        //------------------------------------------------------------------------------

        internal static bool SlopesEqual(ClipperIntPoint pt1, ClipperIntPoint pt2,
                                         ClipperIntPoint pt3, ClipperIntPoint pt4, bool UseFullRange)
        {
            if (UseFullRange)
            {
                return(ClipperInt128.Int128Mul(pt1.Y - pt2.Y, pt3.X - pt4.X) ==
                       ClipperInt128.Int128Mul(pt1.X - pt2.X, pt3.Y - pt4.Y));
            }
            else
            {
                return
                    ((pt1.Y - pt2.Y) * (pt3.X - pt4.X) - (pt1.X - pt2.X) * (pt3.Y - pt4.Y) == 0);
            }
        }
예제 #3
0
        //------------------------------------------------------------------------------

        internal bool PointIsVertex(ClipperIntPoint pt, ClipperOutPt pp)
        {
            ClipperOutPt pp2 = pp;

            do
            {
                if (pp2.Pt == pt)
                {
                    return(true);
                }
                pp2 = pp2.Next;
            }while (pp2 != pp);
            return(false);
        }
예제 #4
0
        //------------------------------------------------------------------------------

        internal bool Pt2IsBetweenPt1AndPt3(ClipperIntPoint pt1, ClipperIntPoint pt2, ClipperIntPoint pt3)
        {
            if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2))
            {
                return(false);
            }
            else if (pt1.X != pt3.X)
            {
                return((pt2.X > pt1.X) == (pt2.X < pt3.X));
            }
            else
            {
                return((pt2.Y > pt1.Y) == (pt2.Y < pt3.Y));
            }
        }
예제 #5
0
        //------------------------------------------------------------------------------

        void RangeTest(ClipperIntPoint Pt, ref bool useFullRange)
        {
            if (useFullRange)
            {
                if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange)
                {
                    throw new ClipperException("Coordinate outside allowed range");
                }
            }
            else if (Pt.X > loRange || Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange)
            {
                useFullRange = true;
                RangeTest(Pt, ref useFullRange);
            }
        }
예제 #6
0
        public static ClipperDoublePoint GetUnitNormal(ClipperIntPoint pt1, ClipperIntPoint pt2)
        {
            double dx = (pt2.X - pt1.X);
            double dy = (pt2.Y - pt1.Y);

            if ((dx == 0) && (dy == 0))
            {
                return(new ClipperDoublePoint());
            }

            var f = 1 * 1.0 / Math.Sqrt(dx * dx + dy * dy);

            dx *= f;
            dy *= f;

            return(new ClipperDoublePoint(dy, -dx));
        }
예제 #7
0
        //------------------------------------------------------------------------------

        internal bool PointOnPolygon(ClipperIntPoint pt, ClipperOutPt pp, bool UseFullRange)
        {
            ClipperOutPt pp2 = pp;

            while (true)
            {
                if (PointOnLineSegment(pt, pp2.Pt, pp2.Next.Pt, UseFullRange))
                {
                    return(true);
                }
                pp2 = pp2.Next;
                if (pp2 == pp)
                {
                    break;
                }
            }
            return(false);
        }
예제 #8
0
        //------------------------------------------------------------------------------

        internal bool PointOnLineSegment(ClipperIntPoint pt,
                                         ClipperIntPoint linePt1, ClipperIntPoint linePt2, bool UseFullRange)
        {
            if (UseFullRange)
            {
                return(((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) ||
                       ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) ||
                       (((pt.X > linePt1.X) == (pt.X < linePt2.X)) &&
                        ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) &&
                        ((ClipperInt128.Int128Mul((pt.X - linePt1.X), (linePt2.Y - linePt1.Y)) ==
                          ClipperInt128.Int128Mul((linePt2.X - linePt1.X), (pt.Y - linePt1.Y))))));
            }
            else
            {
                return(((pt.X == linePt1.X) && (pt.Y == linePt1.Y)) ||
                       ((pt.X == linePt2.X) && (pt.Y == linePt2.Y)) ||
                       (((pt.X > linePt1.X) == (pt.X < linePt2.X)) &&
                        ((pt.Y > linePt1.Y) == (pt.Y < linePt2.Y)) &&
                        ((pt.X - linePt1.X) * (linePt2.Y - linePt1.Y) ==
                         (linePt2.X - linePt1.X) * (pt.Y - linePt1.Y))));
            }
        }
예제 #9
0
        public void AddPath(List <ClipperIntPoint> path, ClipperJoinType joinType, ClipperEndType endType)
        {
            var highI = path.Count - 1;

            if (highI < 0)
            {
                return;
            }
            var newNode = new ClipperPolyNode
            {
                JoinType = joinType,
                EndType  = endType
            };

            //strip duplicate points from path and also get index to the lowest point ...
            if (endType == ClipperEndType.ClosedLine || endType == ClipperEndType.ClosedPolygon)
            {
                while (highI > 0 && path[0] == path[highI])
                {
                    highI--;
                }
            }

            newNode.Polygon.Capacity = highI + 1;
            newNode.Polygon.Add(path[0]);
            int j = 0, k = 0;

            for (var i = 1; i <= highI; i++)
            {
                if (newNode.Polygon[j] != path[i])
                {
                    j++;
                    newNode.Polygon.Add(path[i]);
                    if (path[i].Y > newNode.Polygon[k].Y ||
                        (path[i].Y == newNode.Polygon[k].Y &&
                         path[i].X < newNode.Polygon[k].X))
                    {
                        k = j;
                    }
                }
            }

            if (endType == ClipperEndType.ClosedPolygon && j < 2)
            {
                return;
            }

            polyNodes.AddChild(newNode);

            //if this path's lowest pt is lower than all the others then update m_lowest
            if (endType != ClipperEndType.ClosedPolygon)
            {
                return;
            }

            if (lowest.X < 0)
            {
                lowest = new ClipperIntPoint(polyNodes.ChildCount - 1, k);
            }
            else
            {
                var ip = polyNodes.Children[(int)lowest.X].Polygon[(int)lowest.Y];
                if (newNode.Polygon[k].Y > ip.Y ||
                    (newNode.Polygon[k].Y == ip.Y &&
                     newNode.Polygon[k].X < ip.X))
                {
                    lowest = new ClipperIntPoint(polyNodes.ChildCount - 1, k);
                }
            }
        }