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 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); }
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); }