Пример #1
0
 internal void Remove(Event @event)
 {
     var index = _list.IndexOfValue(@event);
     if (index != -1)
     {
         _list.RemoveAt(index);
     }
 }
Пример #2
0
        public void Compute(HashSet<Point> points, int width, int height)
        {
            _root = null;
            _width = width;
            _height = height;

            if (points.Count < 2)
            {
                return;
            }

            Edges = new List<Edge>();
            Cells = new List<Cell>();
            _queue = new Queue();

            foreach (Point point in points)
            {
                var @event = new Event(point, true);
                var cell = new Cell(point);
                point.Cell = cell;
                _queue.Enqueue(@event);
                Cells.Add(cell);
            }

            while (!_queue.IsEmpty())
            {
                Event @event = _queue.Dequeue();
                _ly = @event.Point.Y;

                if (@event.IsParabola)
                {
                    InsertParabola(@event.Point);
                }
                else
                {
                    RemoveParabola(@event);
                }

                _lasty = @event.Point.Y;
            }

            FinishEdge(_root);

            for (var i = 0; i < Edges.Count; i++)
            {
                if (Edges[i].Neighbour != null)
                {
                    Edges[i].Start = Edges[i].Neighbour.End;
                }
            }
        }
Пример #3
0
 internal void Enqueue(Event @event)
 {
     _list.Add(@event.Point.Y, @event);
 }
Пример #4
0
        private void CheckCircle(Parabola b)
        {
            Parabola lp = GetLeftParent(b);
            Parabola rp = GetRightParent(b);

            Parabola a = GetLeftChild(lp);
            Parabola c = GetRightChild(rp);

            if (a == null || c == null || Equals(a.Site, c.Site)) return;

            Point s = GetEdgeIntersection(lp.Edge, rp.Edge);
            if (s == null) return;

            double d = Distance(a.Site, s);

            if (s.Y - d >= _ly) return;

            var e = new Event(new Point(s.X, s.Y - d), false);

            b.CircleEvent = e;
            e.Arch = b;
            _queue.Enqueue(e);
        }
Пример #5
0
        private void RemoveParabola(Event e)
        {
            Parabola p1 = e.Arch;

            Parabola xl = GetLeftParent(p1);
            Parabola xr = GetRightParent(p1);

            Parabola p0 = GetLeftChild(xl);
            Parabola p2 = GetRightChild(xr);

            if (p0.CircleEvent != null)
            {
                _queue.Remove(p0.CircleEvent);
                p0.CircleEvent = null;
            }
            if (p2.CircleEvent != null)
            {
                _queue.Remove(p2.CircleEvent);
                p2.CircleEvent = null;
            }

            var p = new Point(e.Point.X, GetY(p1.Site, e.Point.X));

            if (Equals(p0.Site.Cell.Last, p1.Site.Cell.First)) p1.Site.Cell.AddLeft(p);
            else p1.Site.Cell.AddRight(p);

            p0.Site.Cell.AddRight(p);
            p2.Site.Cell.AddLeft(p);

            _lasty = e.Point.Y;

            xl.Edge.End = p;
            xr.Edge.End = p;

            Parabola higher = null;
            Parabola par = p1;
            while (par != _root)
            {
                par = par.Parent;
                if (par == xl)
                {
                    higher = xl;
                }
                if (par == xr)
                {
                    higher = xr;
                }
            }

            higher.Edge = new Edge(p, p0.Site, p2.Site);

            Edges.Add(higher.Edge);

            Parabola gparent = p1.Parent.Parent;
            if (p1.Parent.Left == p1)
            {
                if (gparent.Left == p1.Parent) gparent.Left = p1.Parent.Right;
                else p1.Parent.Parent.Right = p1.Parent.Right;
            }
            else
            {
                if (gparent.Left == p1.Parent) gparent.Left = p1.Parent.Left;
                else gparent.Right = p1.Parent.Left;
            }

            CheckCircle(p0);
            CheckCircle(p2);
        }