Ejemplo n.º 1
0
 public void DeleteTest()
 {
     CreateTree();
     Assert.IsTrue(m_tree.Delete(5));
     Assert.IsTrue(m_tree.Delete(-999));
     Assert.IsFalse(m_tree.Delete(5));
     Assert.IsTrue(m_tree.Delete(0));
     Assert.IsFalse(m_tree.Delete(0));
 }
        public static void Main()
        {
            var tree = new AATree<int>();
            Console.WriteLine("The AA tree created.");
            var nums = new[] { -5, 20, 14, 11, 8, -3, 111, 7, 100, -55 };
            for (int i = 0; i < nums.Length; i++)
            {
                AddNumber(tree, nums[i]);
            }

            Console.WriteLine("\n\nTree after we remove element:\n");
            tree.Delete(14, tree.Root);
            DisplayTree(tree.Root, string.Empty);
        }
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));
        }