public Vector3 GetBeachLine(float x, float ly)
        {
            if (m_parabolas == null || m_parabolas.Count == 0)
            {
                return(new Vector3(x, 0, m_border.HalfHeight));
            }

            float minValue      = 0f;
            float cacheMinValue = 0f;

            for (int i = 0; i < m_parabolas.Count; i++)
            {
                cacheMinValue = VParabolaUtils.GetParabolaValueZ(m_parabolas[i].FocusPoint, ly, x);

                if (i == 0)
                {
                    minValue = cacheMinValue;
                    continue;
                }

                if (cacheMinValue < minValue)
                {
                    minValue = cacheMinValue;
                }
            }

            return(new Vector3(x, 0, minValue));
        }
        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);
        }