public HalfEdge Init(Edge edge, Side? side) { Edge = edge; LeftOrRight = side; NextInPriorityQueue = null; Vertex = null; return this; }
public void ReallyDispose() { EdgeListLeftNeighbor = null; EdgeListRightNeighbor = null; NextInPriorityQueue = null; Edge = null; LeftOrRight = null; Vertex = null; pool.Push(this); }
public static Vertex Intersect(HalfEdge halfEdge0, HalfEdge halfEdge1) { Edge edge; HalfEdge halfEdge; var edge0 = halfEdge0.Edge; var edge1 = halfEdge1.Edge; if (edge0 == null || edge1 == null) { return null; } if (edge0.RightSite == edge1.RightSite) { return null; } var determinant = edge0.A * edge1.B - edge0.B * edge1.A; if (-1.0e-10 < determinant && determinant < 1.0e-10) { // the edges are parallel return null; } var intersectionX = (edge0.C * edge1.B - edge1.C * edge0.B) / determinant; var intersectionY = (edge1.C * edge0.A - edge0.C * edge1.A) / determinant; if (Voronoi.CompareByYThenX(edge0.RightSite, edge1.RightSite) < 0) { halfEdge = halfEdge0; edge = edge0; } else { halfEdge = halfEdge1; edge = edge1; } var rightOfSite = intersectionX >= edge.RightSite.X; if ((rightOfSite && halfEdge.LeftOrRight == Side.Left) || (!rightOfSite && halfEdge.LeftOrRight == Side.Right)) return null; return Create(intersectionX, intersectionY); }
public void Insert(HalfEdge halfEdge) { HalfEdge next; var insertionBucket = Bucket(halfEdge); if (insertionBucket < minBucket) { minBucket = insertionBucket; } var previous = hash[insertionBucket]; while ((next = previous.NextInPriorityQueue) != null && (halfEdge.YStar > next.YStar || (halfEdge.YStar == next.YStar && halfEdge.Vertex.X > next.Vertex.X))) { previous = next; } halfEdge.NextInPriorityQueue = previous.NextInPriorityQueue; previous.NextInPriorityQueue = halfEdge; count++; }
public void Dispose() { var halfEdge = LeftEnd; while (halfEdge != RightEnd) { var prevHalfEdge = halfEdge; halfEdge = halfEdge.EdgeListRightNeighbor; prevHalfEdge.Dispose(); } LeftEnd = null; RightEnd.Dispose(); RightEnd = null; int i; //todo: might not be needed for (i = 0; i < hashSize; ++i) { hash[i] = null; } hash = null; }
public void Remove(HalfEdge halfEdge) { halfEdge.EdgeListLeftNeighbor.EdgeListRightNeighbor = halfEdge.EdgeListRightNeighbor; halfEdge.EdgeListRightNeighbor.EdgeListLeftNeighbor = halfEdge.EdgeListLeftNeighbor; halfEdge.Edge = Edge.Deleted; halfEdge.EdgeListLeftNeighbor = halfEdge.EdgeListRightNeighbor = null; }
public void Insert(HalfEdge lb, HalfEdge newHalfEdge) { newHalfEdge.EdgeListLeftNeighbor = lb; newHalfEdge.EdgeListRightNeighbor = lb.EdgeListRightNeighbor; lb.EdgeListRightNeighbor.EdgeListLeftNeighbor = newHalfEdge; lb.EdgeListRightNeighbor = newHalfEdge; }
private static Site RightRegion(HalfEdge halfEdge, Site bottomMostSite) { var edge = halfEdge.Edge; return edge == null ? bottomMostSite : edge.Site(SideHelper.Other((Side)halfEdge.LeftOrRight)); }
private static Site RightRegion(HalfEdge halfEdge, Site bottomMostSite) { var edge = halfEdge.Edge; return(edge == null ? bottomMostSite : edge.Site(SideHelper.Other((Side)halfEdge.LeftOrRight))); }
private void FortunesAlgorithm() { var newIntStar = Vector2.zero; var dataBounds = sites.GetSiteBounds(); var sqrtSiteCount = (int)(Mathf.Sqrt(sites.Count + 4)); var heap = new HalfEdgePriorityQueue(dataBounds.y, dataBounds.height, sqrtSiteCount); var edgeList = new EdgeList(dataBounds.x, dataBounds.width, sqrtSiteCount); var halfEdges = new List <HalfEdge>(); var vertices = new List <Vertex>(); var bottomMostSite = sites.Next(); var newSite = sites.Next(); for (;;) { if (heap.Empty() == false) { newIntStar = heap.Min(); } Site bottomSite; Vertex vertex; HalfEdge lbnd; HalfEdge rbnd; HalfEdge bisector; Edge edge; if (newSite != null && (heap.Empty() || CompareByYThenX(newSite, newIntStar) < 0)) { /* new site is smallest */ //trace("smallest: new site " + newSite); // Step 8: lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coordinate); // the Halfedge just to the left of newSite //trace("lbnd: " + lbnd); rbnd = lbnd.EdgeListRightNeighbor; // the Halfedge just to the right //trace("rbnd: " + rbnd); bottomSite = RightRegion(lbnd, bottomMostSite); // this is the same as leftRegion(rbnd) // this Site determines the region containing the new site //trace("new Site is in region of existing site: " + bottomSite); // Step 9: edge = Edge.CreateBisectingEdge(bottomSite, newSite); //trace("new edge: " + edge); Edges.Add(edge); bisector = HalfEdge.Create(edge, Side.Left); halfEdges.Add(bisector); // inserting two Halfedges into edgeList constitutes Step 10: // insert bisector to the right of lbnd: edgeList.Insert(lbnd, bisector); // first half of Step 11: if ((vertex = Vertex.Intersect(lbnd, bisector)) != null) { vertices.Add(vertex); heap.Remove(lbnd); lbnd.Vertex = vertex; lbnd.YStar = vertex.Y + newSite.Distance(vertex); heap.Insert(lbnd); } lbnd = bisector; bisector = HalfEdge.Create(edge, Side.Right); halfEdges.Add(bisector); // second Halfedge for Step 10: // insert bisector to the right of lbnd: edgeList.Insert(lbnd, bisector); // second half of Step 11: if ((vertex = Vertex.Intersect(bisector, rbnd)) != null) { vertices.Add(vertex); bisector.Vertex = vertex; bisector.YStar = vertex.Y + newSite.Distance(vertex); heap.Insert(bisector); } newSite = sites.Next(); } else if (heap.Empty() == false) { /* intersection is smallest */ lbnd = heap.ExtractMin(); var llbnd = lbnd.EdgeListLeftNeighbor; rbnd = lbnd.EdgeListRightNeighbor; var rrbnd = rbnd.EdgeListRightNeighbor; bottomSite = LeftRegion(lbnd, bottomMostSite); var topSite = RightRegion(rbnd, bottomMostSite); // these three sites define a Delaunay triangle // (not actually using these for anything...) //_triangles.push(new Triangle(bottomSite, topSite, rightRegion(lbnd))); var v = lbnd.Vertex; v.SetIndex(); lbnd.Edge.SetVertex((Side)lbnd.LeftOrRight, v); rbnd.Edge.SetVertex((Side)rbnd.LeftOrRight, v); edgeList.Remove(lbnd); heap.Remove(rbnd); edgeList.Remove(rbnd); var leftRight = Side.Left; if (bottomSite.Y > topSite.Y) { var tempSite = bottomSite; bottomSite = topSite; topSite = tempSite; leftRight = Side.Right; } edge = Edge.CreateBisectingEdge(bottomSite, topSite); Edges.Add(edge); bisector = HalfEdge.Create(edge, leftRight); halfEdges.Add(bisector); edgeList.Insert(llbnd, bisector); edge.SetVertex(SideHelper.Other(leftRight), v); if ((vertex = Vertex.Intersect(llbnd, bisector)) != null) { vertices.Add(vertex); heap.Remove(llbnd); llbnd.Vertex = vertex; llbnd.YStar = vertex.Y + bottomSite.Distance(vertex); heap.Insert(llbnd); } if ((vertex = Vertex.Intersect(bisector, rrbnd)) != null) { vertices.Add(vertex); bisector.Vertex = vertex; bisector.YStar = vertex.Y + bottomSite.Distance(vertex); heap.Insert(bisector); } } else { break; } } // heap should be empty now heap.Dispose(); edgeList.Dispose(); foreach (var halfEdge in halfEdges) { halfEdge.ReallyDispose(); } halfEdges.Clear(); // we need the vertices to clip the edges foreach (var e in Edges) { e.ClipVertices(Bounds); } // but we don't actually ever use them again! foreach (var v in vertices) { v.Dispose(); } vertices.Clear(); }
public void Remove(HalfEdge halfEdge) { HalfEdge previous; var removalBucket = Bucket(halfEdge); if (halfEdge.Vertex == null) return; previous = hash[removalBucket]; while (previous.NextInPriorityQueue != halfEdge) { previous = previous.NextInPriorityQueue; } previous.NextInPriorityQueue = halfEdge.NextInPriorityQueue; count--; halfEdge.Vertex = null; halfEdge.NextInPriorityQueue = null; halfEdge.Dispose(); }
private int Bucket(HalfEdge halfEdge) { var theBucket = (int)((halfEdge.YStar - yMin) / deltaY * hashSize); if (theBucket < 0) theBucket = 0; if (theBucket >= hashSize) theBucket = hashSize - 1; return theBucket; }