void ProcessLeftVertex(VertexEvent leftVertexEvent, PolylinePoint nextVertex) { Debug.Assert(Z == leftVertexEvent.Site * SweepDirection); var site = leftVertexEvent.Site; ProcessPrevSegmentForLeftVertex(leftVertexEvent, site); Point delta = nextVertex.Point - leftVertexEvent.Site; double deltaX = delta * DirectionPerp; double deltaZ = delta * SweepDirection; if (deltaZ <= ApproximateComparer.DistanceEpsilon) { if (deltaX < 0 && deltaZ >= 0) { EnqueueEvent(new LeftVertexEvent(nextVertex)); } } else { //deltaZ>epsilon InsertLeftSide(new LeftObstacleSide(leftVertexEvent.Vertex)); EnqueueEvent(new LeftVertexEvent(nextVertex)); } //ShowAtPoint(leftVertexEvent.Site); RestrictEdgeFromTheLeftOfEvent(leftVertexEvent.Vertex); }
void ProcessRightVertex(VertexEvent rightVertexEvent, PolylinePoint nextVertex) { Debug.Assert(Z == rightVertexEvent.Site * SweepDirection); var site = rightVertexEvent.Site; ProcessPrevSegmentForRightVertex(rightVertexEvent, site); var delta = nextVertex.Point - rightVertexEvent.Site; var deltaX = delta * DirectionPerp; var deltaZ = delta * SweepDirection; if (deltaZ <= ApproximateComparer.DistanceEpsilon) { if (deltaX > 0 && deltaZ >= 0) { EnqueueEvent(new RightVertexEvent(nextVertex)); } else { RestrictEdgeContainerToTheRightOfEvent(rightVertexEvent.Vertex); } } else { //deltaZ>epsilon InsertRightSide(new RightObstacleSide(rightVertexEvent.Vertex)); EnqueueEvent(new RightVertexEvent(nextVertex)); RestrictEdgeContainerToTheRightOfEvent(rightVertexEvent.Vertex); } }
public void VertexChanged(VertexEvent vertexEvent) { foreach (var i in Parents) { ManagementControl.Instance.CurrentDocument.ObjectsDictionary[i].OnDataChange(vertexEvent); } }
public void CheckCircle(BeachArc mid) { BeachEdge leftParent = BeachNode.GetLeftParent(mid); BeachEdge rightParent = BeachNode.GetRightParent(mid); BeachArc left = BeachNode.GetLeftChild(leftParent); BeachArc right = BeachNode.GetRightChild(rightParent); if (left == null || right == null || left.site == right.site) { return; } Vector2 s = GetEdgeIntersection(leftParent.edge, rightParent.edge); if (float.IsNaN(s.x) || float.IsNaN(s.y)) { return; } float dx = left.site.pos.x - s.x; float dy = left.site.pos.y - s.y; float d = Mathf.Sqrt((dx * dx) + (dy * dy)); if (s.y - d >= sweep) { return; } VertexEvent ev = new VertexEvent(left, mid, right); mid.ev = ev; events.Add(ev); }
private void Generate() { // We'll use a sweeping algorithm to calculate the vertices and edges // Start with a priority queue for our events, initially storing // all our site events (each cell) sorted by y-coord SortedSet <VoronoiEvent> events = new SortedSet <VoronoiEvent>(new VoronoiEventComparer()); foreach (Cell cell in diagram.cells) { events.Add(new SiteEvent { site = cell }); } float sweep = ConfigurationManager.Instance.height; BeachTree beach = new BeachTree(ConfigurationManager.Instance.width, ConfigurationManager.Instance.height, diagram, events); while (events.Count > 0) { VoronoiEvent e = events.Min; events.Remove(e); sweep = e.pos.y; beach.sweep = e.pos.y; if (e.GetType() == typeof(SiteEvent)) { SiteEvent se = (SiteEvent)e; beach.Insert(se.site); } else { VertexEvent ve = (VertexEvent)e; beach.Remove(ve); } } beach.Finish(); List <Edge> halves = diagram.edges.Where(e => e.section != null).ToList(); foreach (Edge e in halves) { e.start.edges.Remove(e); e.start = e.section.end; e.section.left.edges.Remove(e.section); e.section.right.edges.Remove(e.section); e.section.end.edges.Remove(e.section); e.section.start.edges.Remove(e.section); diagram.edges.Remove(e.section); } FixDiagram(); Debug.Log("Done"); ConstructMap(); }
private void ProcessPrevSegmentForLeftVertex(VertexEvent leftVertexEvent, Point site) { var prevSite = leftVertexEvent.Vertex.PrevOnPolyline.Point; var delta = site - prevSite; double deltaZ = delta * SweepDirection; if (deltaZ > ApproximateComparer.DistanceEpsilon) { RemoveLeftSide(new LeftObstacleSide(leftVertexEvent.Vertex.PrevOnPolyline)); } }
void ProcessPrevSegmentForRightVertex(VertexEvent rightVertexEvent, Point site) { var prevSite = rightVertexEvent.Vertex.NextOnPolyline.Point; var delta = site - prevSite; double deltaZ = delta * SweepDirection; if (deltaZ > ApproximateComparer.DistanceEpsilon) { RemoveRightSide(new RightObstacleSide(rightVertexEvent.Vertex.NextOnPolyline)); } }
public void RemoveIntersectionWith(Edge edge) { for (int i = 0; i < mIntersections.Count; ++i) { VertexEvent e = mIntersections[i]; if (e.IntersectingEdge == edge) { mIntersections.RemoveAt(i); return; } } }
public int FindIntersectionIndex(Vector3 p) { VecCompare vcompare = new VecCompare(); for (int i = 0; i < mIntersections.Count; ++i) { VertexEvent e = mIntersections[i]; if (vcompare.Compare(e.Point, p) == 0) { return(i); } } return(-1); }
public VertexEvent FindPrevIntersection(Vector3 p, ref Vector3 isect) { VertexEvent prev = null; VecCompare vcompare = new VecCompare(); isect = Line.Start; foreach (VertexEvent e in mIntersections) { if (vcompare.Compare(e.Point, p) >= 0) { break; } isect = e.Point; prev = e; } return(prev); }
public bool AddIntersection(VertexEvent ve) { IComparer <VertexEvent> evcompare = new EventCompare(); VecCompare veccompare = new VecCompare(); for (int i = 0; i < mIntersections.Count; ++i) { VertexEvent ie = mIntersections[i]; if (evcompare.Compare(ie, ve) == 0) { return(false); } if (veccompare.Compare(ie.Point, ve.Point) > 0) { mIntersections.Insert(i, ve); return(true); } } mIntersections.Add(ve); return(true); }
void ProcessVertexEvent(VertexEvent vertexEvent) { Z = GetZ(vertexEvent); var leftVertexEvent = vertexEvent as LeftVertexEvent; if (leftVertexEvent != null) { ProcessLeftVertex(leftVertexEvent, vertexEvent.Vertex.NextOnPolyline); } else { var rightVertexEvent = vertexEvent as RightVertexEvent; if (rightVertexEvent != null) { ProcessRightVertex(rightVertexEvent, vertexEvent.Vertex.PrevOnPolyline); } else { ProcessLeftVertex(vertexEvent, vertexEvent.Vertex.NextOnPolyline); ProcessRightVertex(vertexEvent, vertexEvent.Vertex.PrevOnPolyline); } } }
public void OnDataChange(VertexEvent vertexEvent) { }
public void Remove(VertexEvent e) { BeachArc mid = e.arcs[1]; BeachEdge leftEdge = BeachNode.GetLeftParent(mid); BeachEdge rightEdge = BeachNode.GetRightParent(mid); BeachArc left = BeachNode.GetLeftChild(leftEdge); BeachArc right = BeachNode.GetRightChild(rightEdge); if (left.ev != null) { events.Remove(left.ev); left.ev = null; } if (right.ev != null) { events.Remove(right.ev); right.ev = null; } Vertex end = new Vertex(e.center); diagram.vertices.Add(end); leftEdge.edge.end = end; rightEdge.edge.end = end; diagram.edges.Add(leftEdge.edge); diagram.edges.Add(rightEdge.edge); BeachEdge higher = null; BeachNode par = mid; while (par != root) { par = par.parent; if (par == leftEdge) { higher = leftEdge; } if (par == rightEdge) { higher = rightEdge; } } higher.edge = new Edge(end, left.site, right.site); diagram.edges.Add(higher.edge); BeachEdge gparent = (BeachEdge)mid.parent.parent; if (mid.parent.left == mid) { if (gparent.left == mid.parent) { gparent.left = mid.parent.right; } if (gparent.right == mid.parent) { gparent.right = mid.parent.right; } } else { if (gparent.left == mid.parent) { gparent.left = mid.parent.left; } if (gparent.right == mid.parent) { gparent.right = mid.parent.left; } } CheckCircle(left); CheckCircle(right); }
private IEnumerator GenerateVisualized() { // We'll use a sweeping algorithm to calculate the vertices and edges // Start with a priority queue for our events, initially storing // all our site events (each cell) sorted by y-coord SortedSet <VoronoiEvent> events = new SortedSet <VoronoiEvent>(new VoronoiEventComparer()); foreach (Cell cell in diagram.cells) { events.Add(new SiteEvent { site = cell }); } float sweep = ConfigurationManager.Instance.height; BeachTree beach = new BeachTree(ConfigurationManager.Instance.width, ConfigurationManager.Instance.height, diagram, events); GameObject sweepObj = Instantiate(sweepPrefab, lineRenderersContainer); LineRenderer sweepRend = sweepObj.GetComponentInChildren <LineRenderer>(); GameObject eventObj = Instantiate(eventPrefab, verticesContainer); List <GameObject> beachObjs = new List <GameObject>(); List <GameObject> diagramObjs = new List <GameObject>(); foreach (Cell cell in diagram.cells) { GameObject cellGObject = Instantiate(cellPrefab, cellsContainer); cellGObject.transform.localPosition = cell.pos; cellGObject.transform.GetComponentInChildren <TextMeshPro>().text = cell.name; // TODO implement CellController and initialize it } //MakeBeach(beachObjs, beach.GetPoints(sweep)); sweepRend.SetPositions(new Vector3[] { new Vector2(0, sweep), new Vector2(ConfigurationManager.Instance.width, sweep) }); yield return(new WaitForSeconds(0.05f)); while (events.Count > 0) { VoronoiEvent e = events.Min; events.Remove(e); eventObj.transform.localPosition = e.pos; while (sweep - 0.1f > e.pos.y) { sweep = sweep - 0.1f; beach.sweep = sweep; sweepRend.SetPositions(new Vector3[] { new Vector2(0, sweep), new Vector2(ConfigurationManager.Instance.width, sweep) }); MakeVoronoi(diagramObjs); MakeBeach(beachObjs, beach.GetBeachPoints()); yield return(new WaitForSeconds(0.1f)); } sweep = e.pos.y; beach.sweep = e.pos.y; sweepRend.SetPositions(new Vector3[] { new Vector2(0, sweep), new Vector2(ConfigurationManager.Instance.width, sweep) }); MakeVoronoi(diagramObjs); MakeBeach(beachObjs, beach.GetBeachPoints()); yield return(new WaitForSeconds(0.1f)); if (e.GetType() == typeof(SiteEvent)) { SiteEvent se = (SiteEvent)e; beach.Insert(se.site); } else { VertexEvent ve = (VertexEvent)e; beach.Remove(ve); } MakeVoronoi(diagramObjs); MakeBeach(beachObjs, beach.GetBeachPoints()); yield return(new WaitForSeconds(0.1f)); } Debug.Log("Finished Events"); beach.Finish(); List <Edge> halves = diagram.edges.Where(e => e.section != null).ToList(); foreach (Edge e in halves) { e.start.edges.Remove(e); e.start = e.section.end; e.section.left.edges.Remove(e.section); e.section.right.edges.Remove(e.section); e.section.end.edges.Remove(e.section); e.section.start.edges.Remove(e.section); diagram.edges.Remove(e.section); } FixDiagram(); while (beachObjs.Count > 0) { Destroy(beachObjs[0]); beachObjs.RemoveAt(0); } while (diagramObjs.Count > 0) { Destroy(diagramObjs[0]); diagramObjs.RemoveAt(0); } // Construct current map ConstructMap(); }