private void CheckCircleEvent(VParabola parabola)
        {
            VEdge leftEdge  = parabola.LeftEdge;
            VEdge rightEdge = parabola.RightEdge;

            if (!VEdge.HasValidIntersectPoint(leftEdge, rightEdge))
            {
                return;
            }

            Vector3 intersectPoint = VEdge.GetIntersectPoint(leftEdge, rightEdge);

            float distance = Vector3.Distance(intersectPoint, parabola.FocusPoint);
            float targetLy = intersectPoint.z - distance;

            Vector3 circlePoint = new Vector3(parabola.FocusPoint.x, 0, targetLy);

            VEvent algorithmEvent = new VEvent(circlePoint, false);

            algorithmEvent.Parabola    = parabola;
            algorithmEvent.VertexPoint = intersectPoint;

            parabola.CircleEvent = algorithmEvent;

            m_eventQueues.Add(algorithmEvent);
            SortEventQueues();
        }
        private void AddCircleEvent(VEvent algorithmEvent)
        {
            List <VParabola> removeParabolas = new List <VParabola>();
            VParabola        removeParabola  = algorithmEvent.Parabola;

            VParabola leftParabola  = removeParabola.LeftParabola;
            VParabola rightParabola = removeParabola.RightParabola;

            if (leftParabola == null || rightParabola == null)
            {
                return;
            }

            removeParabolas.Add(removeParabola);

            if (removeParabolas.Count == 0)
            {
                return;
            }

            if (leftParabola.CircleEvent != null)
            {
                m_eventQueues.Remove(leftParabola.CircleEvent);
                leftParabola.CircleEvent = null;
            }

            if (rightParabola.CircleEvent != null)
            {
                m_eventQueues.Remove(rightParabola.CircleEvent);
                rightParabola.CircleEvent = null;
            }

            Vertices.Add(algorithmEvent.VertexPoint);

            VEdge edge = new VEdge(algorithmEvent.VertexPoint, leftParabola.FocusPoint, rightParabola.FocusPoint);

            Edges.Add(edge);

            leftParabola.RightParabola = rightParabola;
            leftParabola.RightEdge     = edge;

            rightParabola.LeftParabola = leftParabola;
            rightParabola.LeftEdge     = edge;

            for (int i = 0; i < removeParabolas.Count; i++)
            {
                m_eventQueues.Remove(removeParabolas[i].CircleEvent);
                removeParabolas[i].CircleEvent = null;
                removeParabolas[i].LeftEdge.SetVertexPoint(algorithmEvent.VertexPoint);
                removeParabolas[i].RightEdge.SetVertexPoint(algorithmEvent.VertexPoint);
                m_parabolas.Remove(removeParabolas[i]);
            }

            CheckCircleEvent(leftParabola);
            CheckCircleEvent(rightParabola);
        }
        public void AddSiteEvent(Vector3 site, float ly)
        {
            if (m_parabolas.Count == 0)
            {
                m_parabolas.Add(new VParabola(site));
                return;
            }

            int       beachLineIndex    = GetBeachLineByX(site.x, ly);
            VParabola beachLineParabola = m_parabolas[beachLineIndex];
            VParabola p0 = null;
            VParabola p1 = null;
            VParabola p2 = null;

            if (beachLineParabola.FocusPoint.z == site.z)
            {
                Vector3 startPoint = new Vector3((beachLineParabola.FocusPoint.x + site.x) / 2, 0, m_border.HalfHeight);
                VEdge   edge       = null;
                if (beachLineParabola.FocusPoint.x < site.x)
                {
                    edge = new VEdge(startPoint, beachLineParabola.FocusPoint, site);

                    p0 = new VParabola(beachLineParabola.FocusPoint);
                    p1 = new VParabola(site);
                }
                else
                {
                    edge = new VEdge(startPoint, site, beachLineParabola.FocusPoint);

                    p0 = new VParabola(site);
                    p1 = new VParabola(beachLineParabola.FocusPoint);
                }

                Edges.Add(edge);

                p0.LeftParabola  = beachLineParabola.LeftParabola;
                p0.LeftEdge      = beachLineParabola.LeftEdge;
                p0.RightEdge     = edge;
                p0.RightParabola = p1;

                p1.LeftParabola  = p0;
                p1.LeftEdge      = edge;
                p1.RightEdge     = beachLineParabola.RightEdge;
                p1.RightParabola = beachLineParabola.RightParabola;

                if (p0.LeftParabola != null)
                {
                    p0.LeftParabola.RightParabola = p0;
                }

                if (p1.RightParabola != null)
                {
                    p1.RightParabola.LeftParabola = p1;
                }

                m_parabolas.RemoveAt(beachLineIndex);
                m_parabolas.Insert(beachLineIndex, p0);
                m_parabolas.Insert(beachLineIndex + 1, p1);

                CheckCircleEvent(p0);
                CheckCircleEvent(p1);

                return;
            }

            if (beachLineParabola.CircleEvent != null)
            {
                m_eventQueues.Remove(beachLineParabola.CircleEvent);
                beachLineParabola.CircleEvent = null;
            }

            Vector3 edgeStartPoint = new Vector3(site.x, 0, VParabolaUtils.GetParabolaValueZ(beachLineParabola.FocusPoint, ly, site.x));
            VEdge   leftEdge       = new VEdge(edgeStartPoint, beachLineParabola.FocusPoint, site);
            VEdge   rightEdge      = new VEdge(edgeStartPoint, site, beachLineParabola.FocusPoint);

            Edges.Add(leftEdge);
            Edges.Add(rightEdge);

            p0 = new VParabola(beachLineParabola.FocusPoint);
            p1 = new VParabola(site);
            p2 = new VParabola(beachLineParabola.FocusPoint);

            p0.LeftParabola  = beachLineParabola.LeftParabola;
            p0.LeftEdge      = beachLineParabola.LeftEdge;
            p0.RightEdge     = leftEdge;
            p0.RightParabola = p1;

            p1.LeftParabola  = p0;
            p1.LeftEdge      = leftEdge;
            p1.RightEdge     = rightEdge;
            p1.RightParabola = p2;

            p2.LeftParabola  = p1;
            p2.LeftEdge      = rightEdge;
            p2.RightEdge     = beachLineParabola.RightEdge;
            p2.RightParabola = beachLineParabola.RightParabola;

            if (p0.LeftParabola != null)
            {
                p0.LeftParabola.RightParabola = p0;
            }

            if (p2.RightParabola != null)
            {
                p2.RightParabola.LeftParabola = p2;
            }

            m_parabolas.RemoveAt(beachLineIndex);
            m_parabolas.Insert(beachLineIndex, p0);
            m_parabolas.Insert(beachLineIndex + 1, p1);
            m_parabolas.Insert(beachLineIndex + 2, p2);

            CheckCircleEvent(p0);
            CheckCircleEvent(p2);
        }