Ejemplo n.º 1
0
    /// <summary>
    /// Computes a list of gridpoints indside the given polygon defined by outerpoints and holes.
    /// </summary>
    /// <param name="rect"></param>
    /// <param name="outerPoints"></param>
    /// <param name="holes"></param>
    /// <param name="n"></param>
    /// <returns></returns>
    private List <Vector2> ComputeGridPoints(Rect rect, List <Vector2> outerPoints, List <List <Vector2> > holes, int n)
    {
        var gridPoints = new List <Vector2>();

        Debug.Log(rect.xMin);
        Debug.Log(rect.xMax);
        Debug.Log(rect.yMin);
        Debug.Log(rect.yMax);
        Debug.Log(rect.width);
        Debug.Log(rect.height);

        for (float x = rect.xMin; x < rect.xMax; x += rect.width / (float)n)
        {
            for (float y = rect.yMin; y < rect.yMax; y += rect.height / (float)n)
            {
                gridPoints.Add(new Vector2(x, y));
            }
        }

        gridPoints = Normalize(rect, agSIZE, gridPoints);

        var tempPoly = new Polygon2DWithHoles(new Polygon2D(outerPoints), holes.Select(h => new Polygon2D(h)));

        for (int i = gridPoints.Count - 1; i >= 0; i--)
        {
            var point = gridPoints[i];
            if (!tempPoly.ContainsInside(point))
            {
                gridPoints.Remove(point);
            }
        }

        return(gridPoints);
    }
 public void ContainsInsideTest()
 {
     Assert.IsTrue(m_squareWithHole.ContainsInside(new Vector2(1.5f, 0)));
     Assert.IsFalse(m_squareWithHole.ContainsInside(new Vector2(0, 0)));
 }
Ejemplo n.º 3
0
        public static Polygon2D Vision(Polygon2DWithHoles polygon, Vector2 x)
        {
            if (!(polygon.ContainsInside(x) || polygon.OnBoundary(x)))
            {
                throw new ArgumentException(x + " is not inside polygon: " + polygon);
            }

            float initAngle;
            var   events = Preprocess(polygon, x, out initAngle);

            var status     = new AATree <StatusItem>();
            var visibility = new List <Vector2>();

            // create ray in positive x direction
            var ray = new Ray2D(Vector2.zero, new Vector2(1f, 0f));

            VisibilityEvent xEvent = null;

            // initialize the status
            foreach (var v in events)
            {
                if (MathUtil.EqualsEps(v.vertex, Vector2.zero))
                {
                    xEvent = v;
                    continue;
                }

                var seg = v.item1.seg;
                if (!seg.IsEndpoint(x))
                {
                    var intersect = seg.Intersect(ray);
                    if (intersect.HasValue && intersect.Value.x > 0 && (seg.Point1.y >= 0 != seg.Point2.y >= 0) &&
                        !MathUtil.EqualsEps(intersect.Value, Vector2.zero))
                    {
                        status.Insert(v.item1);
                    }
                }
            }

            if (xEvent != null)
            {
                if (!xEvent.isHole)
                {
                    status.Insert(xEvent.item1);
                }
                else
                {
                    status.Delete(xEvent.item1);
                }

                if (!xEvent.isHole)
                {
                    status.Delete(xEvent.item2);
                }
                else
                {
                    status.Insert(xEvent.item2);
                }

                if (!xEvent.isHole)
                {
                    visibility.Add(xEvent.item2.seg.Point2);
                    visibility.Add(Vector2.zero);
                    visibility.Add(xEvent.item1.seg.Point1);
                }
                else
                {
                    visibility.Add(xEvent.item2.seg.Point1);
                    visibility.Add(Vector2.zero);
                    visibility.Add(xEvent.item1.seg.Point2);
                }
            }

            // handle events
            StatusItem top        = null;
            var        insertions = new HashSet <StatusItem>();

            if (status.Count > 0)
            {
                status.FindMin(out top);
            }
            for (var i = 0; i < events.Count; i++)
            {
                var v = events[i];

                if (MathUtil.EqualsEps(v.vertex, Vector2.zero))
                {
                    continue;
                }

                ray = new Ray2D(Vector2.zero, v.vertex);

                // first handle deletions

                // handle first segment
                if (status.Contains(v.item1))
                {
                    status.Delete(v.item1);
                }
                else if (insertions.Contains(v.item1))
                {
                    insertions.Remove(v.item1);
                }
                else
                {
                    insertions.Add(v.item1);
                }

                // handle second segment
                if (status.Contains(v.item2))
                {
                    status.Delete(v.item2);
                }
                else if (insertions.Contains(v.item2))
                {
                    insertions.Remove(v.item2);
                }
                else
                {
                    insertions.Add(v.item2);
                }

                // skip if next event colinear with current
                if (i < events.Count - 1 && Line.Colinear(Vector2.zero, v.vertex, events[i + 1].vertex))
                {
                    // skip until all colinear events are handled
                    continue;
                }

                // handle insertions (after potential skip for colinear events
                foreach (var item in insertions)
                {
                    status.Insert(item);
                }
                insertions.Clear();

                StatusItem newTop;
                status.FindMin(out newTop);

                // do stuff if current top different from previous
                if (top != newTop)
                {
                    // add intersections with previous top segment
                    if (top != null)
                    {
                        HandleTopSegment(ref visibility, top.seg, ray);
                    }

                    // add intersections with new top segment
                    if (newTop != null)
                    {
                        HandleTopSegment(ref visibility, newTop.seg, ray);
                    }

                    top = newTop;
                }
            }

            return(Postprocess(visibility, x, initAngle));
        }