// assumes p is ccw ordered, edge is counted as interior (neither case)
        public static bool SegmentIntersectsNonDegenerateConvexPolygonInterior(IntLineSegment2 s, IntVector2[] p)
        {
#if DEBUG
            if (Clockness(p[0], p[1], p[2]) == Clk.Clockwise)
            {
                throw new BadInputException("p not ccw");
            }
            if (p.Length < 3)
            {
                throw new BadInputException("len(p) < 3");
            }
#endif
            var(x, y) = s;
            bool       xInterior = true, yInterior = true;
            IntVector2 a = p[p.Length - 1], b;
            int        i = 0;
            for (; i < p.Length && (xInterior || yInterior); i++, a = b)
            {
                b = p[i];
                var abx = Clockness(a, b, x);
                var aby = Clockness(a, b, y);
                if (abx == Clk.Clockwise && aby == Clk.Clockwise)
                {
                    return(false);
                }
                xInterior &= abx != Clk.Clockwise;
                yInterior &= aby != Clk.Clockwise;
                if (abx == (Clk)(-(int)aby) || abx == Clk.Neither || aby == Clk.Neither)
                {
                    // The below is equivalent to:
                    // // (a, b) places x, y onto opposite half-planes.
                    // // Intersect if (x, y) places a, b onto opposite half-planes.
                    // var xya = Clockness(x, y, a);
                    // var xyb = Clockness(x, y, b);
                    // if (xya != xyb || xya == Clk.Neither || xyb == Clk.Neither) return true;
                    if (IntLineSegment2.Intersects(a.X, a.Y, b.X, b.Y, x.X, x.Y, y.X, y.Y))
                    {
                        return(true);
                    }
                }
            }
            for (; i < p.Length; i++, a = b)
            {
                b = p[i];
                if (IntLineSegment2.Intersects(a.X, a.Y, b.X, b.Y, x.X, x.Y, y.X, y.Y))
                {
                    return(true);
                }
            }
            return(xInterior && yInterior);
        }
 public static bool SegmentIntersectsConvexPolygonInterior(IntLineSegment2 s, IntVector2[] p)
 {
     if (p.Length == 1)
     {
         return(false);
     }
     else if (p.Length == 2)
     {
         return(s.Intersects(new IntLineSegment2(p[0], p[1])));
     }
     else
     {
         return(SegmentIntersectsNonDegenerateConvexPolygonInterior(s, p));
     }
 }
Example #3
0
        public static PolygonContainmentResult SegmentInPolygon(this PolyNode node, IntLineSegment2 query)
        {
            var bvh = node.visibilityGraphNodeData.ContourBvh;

            if (bvh != null)
            {
                if (bvh.Intersects(ref query))
                {
                    return(PolygonContainmentResult.IntersectsPolygon);
                }
            }
            else
            {
                var last = node.Contour[node.Contour.Count - 1];
                var q1   = query.First;
                var q2   = query.Second;
                for (var i = 0; i < node.Contour.Count; i++)
                {
                    var current = node.Contour[i];
                    if ((current == q1 && last == q2) || (current == q2 && last == q1))
                    {
                        return(PolygonContainmentResult.OnPolygon);
                    }
                    if (IntLineSegment2.Intersects(current.X, current.Y, last.X, last.Y, q1.X, q1.Y, q2.X, q2.Y))
                    {
                        return(PolygonContainmentResult.IntersectsPolygon);
                    }
                    last = current;
                }
            }

            // Query segment isn't on-contour or intersecting the contour, so it's either fully in or out.
            var endpointContainment = Clipper.PointInPolygon(query.First, node.Contour);

            if (endpointContainment == PolygonContainmentResult.OnPolygon)
            {
                return(PolygonContainmentResult.IntersectsPolygon);
            }
            return(endpointContainment);
        }