Ejemplo n.º 1
0
        public void FindMinTest()
        {
            CreateTree();
            int val;

            Assert.IsTrue(m_tree.FindMin(out val));
            Assert.AreEqual(-999, val);
        }
    // Test program; should print min and max and nothing else
    public static void Main(string[] args)
    {
        AATree <int> t    = new AATree <int>(-9999);
        const int    NUMS = 40000;
        const int    GAP  = 307;

        Console.WriteLine("Checking... (no bad output means success)");

        t.Insert(NUMS * 2);
        t.Insert(NUMS * 3);
        for (int i = GAP; i != 0; i = (i + GAP) % NUMS)
        {
            t.Insert(i);
        }
        Console.WriteLine("Inserts complete");

        t.Remove(t.FindMax( ));
        for (int i = 1; i < NUMS; i += 2)
        {
            t.Remove(i);
        }
        t.Remove(t.FindMax( ));
        Console.WriteLine("Removes complete");


        if (t.FindMin( ) != 2 || t.FindMax( ) != NUMS - 2)
        {
            Console.WriteLine("FindMin or FindMax error!");
        }

        for (int i = 2; i < NUMS; i += 2)
        {
            if (t.Find(i) != i)
            {
                Console.WriteLine("Error: find fails for " + i);
            }
        }

        for (int i = 1; i < NUMS; i += 2)
        {
            if (t.Contains(i))
            {
                Console.WriteLine("Error: Found deleted item " + i);
            }
        }
    }
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));
        }