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);
        }
Example #3
0
        public static bool HasValidIntersectPoint(VEdge leftEdge, VEdge rightEdge)
        {
            if (leftEdge == null || rightEdge == null)
            {
                return(false);
            }

            if (leftEdge.m_lerp == rightEdge.m_lerp)
            {
                return(false);
            }

            Vector3 intersectPoint = GetIntersectPoint(leftEdge, rightEdge);

            bool valid = true;

            if (!leftEdge.IsInfinityLerp())
            {
                if (leftEdge.m_direction == Direction.Left)
                {
                    valid &= intersectPoint.x < leftEdge.StartPoint.x;
                }
                else
                {
                    valid &= intersectPoint.x > leftEdge.StartPoint.x;
                }
            }

            if (!rightEdge.IsInfinityLerp())
            {
                if (rightEdge.m_direction == Direction.Left)
                {
                    valid &= intersectPoint.x < rightEdge.StartPoint.x;
                }
                else
                {
                    valid &= intersectPoint.x > rightEdge.StartPoint.x;
                }
            }

            return(valid);
        }
Example #4
0
        public static Vector3 GetIntersectPoint(VEdge leftEdge, VEdge rightEdge)
        {
            Vector3 intersectPoint = Vector3.zero;

            if (leftEdge.IsInfinityLerp())
            {
                intersectPoint.x = leftEdge.StartPoint.x;
                intersectPoint.z = rightEdge.m_lerp * intersectPoint.x + rightEdge.m_intercept;
            }
            else if (rightEdge.IsInfinityLerp())
            {
                intersectPoint.x = rightEdge.StartPoint.x;
                intersectPoint.z = leftEdge.m_lerp * intersectPoint.x + leftEdge.m_intercept;
            }
            else
            {
                intersectPoint.x = (rightEdge.m_intercept - leftEdge.m_intercept) / (leftEdge.m_lerp - rightEdge.m_lerp);
                intersectPoint.z = leftEdge.m_lerp * intersectPoint.x + leftEdge.m_intercept;
            }

            return(intersectPoint);
        }
        private void FinishEdge()
        {
            List <Vector3> removeVertices = new List <Vector3>();

            for (int i = 0; i < Vertices.Count; i++)
            {
                if (Vertices[i].x > m_border.HalfWidth || Vertices[i].x <-m_border.HalfWidth ||
                                                                         Vertices[i].z> m_border.HalfHeight || Vertices[i].z < -m_border.HalfHeight)
                {
                    removeVertices.Add(Vertices[i]);
                }
            }

            for (int i = 0; i < removeVertices.Count; i++)
            {
                Vertices.Remove(removeVertices[i]);
            }

            VEdge cacheEdge = null;

            for (int i = 0; i < Edges.Count; i++)
            {
                cacheEdge = Edges[i];
                cacheEdge.Finish(m_border);

                if (cacheEdge.LeftSite.x == cacheEdge.RightSite.x)
                {
                    if (cacheEdge.LeftSite.z < cacheEdge.RightSite.z)
                    {
                        Vector3 temp = cacheEdge.LeftSite;
                        cacheEdge.LeftSite  = cacheEdge.RightSite;
                        cacheEdge.RightSite = temp;
                    }
                }
                else
                {
                    if (cacheEdge.LeftSite.x < cacheEdge.RightSite.x)
                    {
                        Vector3 temp = cacheEdge.LeftSite;
                        cacheEdge.LeftSite  = cacheEdge.RightSite;
                        cacheEdge.RightSite = temp;
                    }
                }
            }

            List <VEdge> validEdges = new List <VEdge>();

            for (int i = 0; i < Edges.Count; i++)
            {
                cacheEdge = Edges[i];

                if (validEdges.Contains(cacheEdge))
                {
                    continue;
                }

                validEdges.Add(cacheEdge);
            }

            Edges = validEdges;
        }
        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);
        }