Insert() публичный Метод

public Insert ( Halfedge lb, Halfedge newHalfedge ) : void
lb Halfedge
newHalfedge Halfedge
Результат void
Пример #1
0
        private void FortunesAlgorithm()
        {
            Site     newSite, bottomSite, topSite, tempSite;
            Vertex   v, vertex;
            PointF   newintstar = PointF.Empty;
            LR       leftRight;
            Halfedge lbnd, rbnd, llbnd, rrbnd, bisector;
            Edge     edge;

            RectangleF dataBounds = _sites.GetSitesBounds();

            int sqrt_nsites            = (int)(Math.Sqrt(_sites.Length + 4));
            HalfedgePriorityQueue heap = new HalfedgePriorityQueue(dataBounds.Y, dataBounds.Height, sqrt_nsites);
            EdgeList        edgeList   = new EdgeList(dataBounds.X, dataBounds.Width, sqrt_nsites);
            List <Halfedge> halfEdges  = new List <Halfedge>();
            List <Vertex>   vertices   = new List <Vertex>();

            Site bottomMostSite = _sites.Next();

            newSite = _sites.Next();

            for (; ;)
            {
                if (heap.Empty() == false)
                {
                    newintstar = heap.Min();
                }

                if (newSite != null &&
                    (heap.Empty() || CompareByYThenX(newSite, newintstar) < 0))
                {
                    /* new site is smallest */
                    //trace("smallest: new site " + newSite);

                    // Step 8:
                    lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord()); // 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, LR.LEFT);
                    halfEdges.Add(bisector);
                    // inserting two Halfedges into edgeList static readonlyitutes 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.Dist(vertex);
                        heap.Insert(lbnd);
                    }

                    lbnd     = bisector;
                    bisector = Halfedge.Create(edge, LR.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.Dist(vertex);
                        heap.Insert(bisector);
                    }

                    newSite = _sites.Next();
                }
                else if (heap.Empty() == false)
                {
                    /* intersection is smallest */
                    lbnd       = heap.ExtractMin();
                    llbnd      = lbnd.edgeListLeftNeighbor;
                    rbnd       = lbnd.edgeListRightNeighbor;
                    rrbnd      = rbnd.edgeListRightNeighbor;
                    bottomSite = LeftRegion(lbnd, bottomMostSite);
                    topSite    = RightRegion(rbnd, bottomMostSite);
                    // these three sites define a Delaunay triangle
                    // (not actually using these for anything...)
                    //_triangles.Add(new Triangle(bottomSite, topSite, rightRegion(lbnd)));

                    v = lbnd.vertex;
                    v.SetIndex();
                    lbnd.edge.SetVertex(lbnd.leftRight, v);
                    rbnd.edge.SetVertex(rbnd.leftRight, v);
                    edgeList.Remove(lbnd);
                    heap.Remove(rbnd);
                    edgeList.Remove(rbnd);
                    leftRight = LR.LEFT;
                    if (bottomSite.Y > topSite.Y)
                    {
                        tempSite = bottomSite; bottomSite = topSite; topSite = tempSite; leftRight = LR.RIGHT;
                    }
                    edge = Edge.CreateBisectingEdge(bottomSite, topSite);
                    _edges.Add(edge);
                    bisector = Halfedge.Create(edge, leftRight);
                    halfEdges.Add(bisector);
                    edgeList.Insert(llbnd, bisector);
                    edge.SetVertex(LR.Other(leftRight), v);
                    if ((vertex = Vertex.Intersect(llbnd, bisector)) != null)
                    {
                        vertices.Add(vertex);
                        heap.Remove(llbnd);
                        llbnd.vertex = vertex;
                        llbnd.ystar  = vertex.Y + bottomSite.Dist(vertex);
                        heap.Insert(llbnd);
                    }
                    if ((vertex = Vertex.Intersect(bisector, rrbnd)) != null)
                    {
                        vertices.Add(vertex);
                        bisector.vertex = vertex;
                        bisector.ystar  = vertex.Y + bottomSite.Dist(vertex);
                        heap.Insert(bisector);
                    }
                }
                else
                {
                    break;
                }
            }

            // heap should be empty now
            heap.Dispose();
            edgeList.Dispose();

            foreach (Halfedge halfEdge in halfEdges)
            {
                halfEdge.ReallyDispose();
            }
            halfEdges.Clear();

            // we need the vertices to clip the edges
            foreach (Edge edge2 in _edges)
            {
                edge2.ClipVertices(_plotBounds);
            }
            // but we don't actually ever use them again!
            foreach (Vertex vertex2 in vertices)
            {
                vertex2.Dispose();
            }
            vertices.Clear();
        }
Пример #2
0
		private void FortunesAlgorithm ()
		{
			Site newSite, bottomSite, topSite, tempSite;
			Vertex v, vertex;
			Vector2 newintstar = Vector2.zero; //Because the compiler doesn't know that it will have a value - Julian
			Side leftRight;
			Halfedge lbnd, rbnd, llbnd, rrbnd, bisector;
			Edge edge;
			
			Rect dataBounds = _sites.GetSitesBounds ();
			
			int sqrt_nsites = (int)(Mathf.Sqrt (_sites.Count + 4));
			HalfedgePriorityQueue heap = new HalfedgePriorityQueue (dataBounds.y, dataBounds.height, sqrt_nsites);
			EdgeList edgeList = new EdgeList (dataBounds.x, dataBounds.width, sqrt_nsites);
			List<Halfedge> halfEdges = new List<Halfedge> ();
			List<Vertex> vertices = new List<Vertex> ();
			
			fortunesAlgorithm_bottomMostSite = _sites.Next ();
			newSite = _sites.Next ();
			
			for (;;) {
				if (heap.Empty () == false) {
					newintstar = heap.Min ();
				}
			
				if (newSite != null 
					&& (heap.Empty () || CompareByYThenX (newSite, newintstar) < 0)) {
					/* new site is smallest */
					//trace("smallest: new site " + newSite);
					
					// Step 8:
					lbnd = edgeList.EdgeListLeftNeighbor (newSite.Coord);	// the Halfedge just to the left of newSite
					//trace("lbnd: " + lbnd);
					rbnd = lbnd.edgeListRightNeighbor;		// the Halfedge just to the right
					//trace("rbnd: " + rbnd);
					bottomSite = FortunesAlgorithm_rightRegion (lbnd);		// 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.Dist (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.Dist (vertex);
						heap.Insert (bisector);	
					}
					
					newSite = _sites.Next ();	
				} else if (heap.Empty () == false) {
					/* intersection is smallest */
					lbnd = heap.ExtractMin ();
					llbnd = lbnd.edgeListLeftNeighbor;
					rbnd = lbnd.edgeListRightNeighbor;
					rrbnd = rbnd.edgeListRightNeighbor;
					bottomSite = FortunesAlgorithm_leftRegion (lbnd);
					topSite = FortunesAlgorithm_rightRegion (rbnd);
					// these three sites define a Delaunay triangle
					// (not actually using these for anything...)
					//_triangles.push(new Triangle(bottomSite, topSite, rightRegion(lbnd)));
					
					v = lbnd.vertex;
					v.SetIndex ();
					lbnd.edge.SetVertex ((Side)lbnd.leftRight, v);
					rbnd.edge.SetVertex ((Side)rbnd.leftRight, v);
					edgeList.Remove (lbnd); 
					heap.Remove (rbnd);
					edgeList.Remove (rbnd); 
					leftRight = Side.LEFT;
					if (bottomSite.y > topSite.y) {
						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.Dist (vertex);
						heap.Insert (llbnd);
					}
					if ((vertex = Vertex.Intersect (bisector, rrbnd)) != null) {
						vertices.Add (vertex);
						bisector.vertex = vertex;
						bisector.ystar = vertex.y + bottomSite.Dist (vertex);
						heap.Insert (bisector);
					}
				} else {
					break;
				}
			}
			
			// heap should be empty now
			heap.Dispose ();
			edgeList.Dispose ();
			
			for (int hIndex = 0; hIndex<halfEdges.Count; hIndex++) {
				Halfedge halfEdge = halfEdges [hIndex];
				halfEdge.ReallyDispose ();
			}
			halfEdges.Clear ();
			
			// we need the vertices to clip the edges
			for (int eIndex = 0; eIndex<_edges.Count; eIndex++) {
				edge = _edges [eIndex];
				edge.ClipVertices (_plotBounds);
			}
			// but we don't actually ever use them again!
			for (int vIndex = 0; vIndex<vertices.Count; vIndex++) {
				vertex = vertices [vIndex];
				vertex.Dispose ();
			}
			vertices.Clear ();
		}
Пример #3
0
        private void FortunesAlgorithm()
        {
            Site     newSite, bottomSite, topSite, tempSite;
            Vertex   v, vertex;
            Vector2  newintstar = Vector2.zero;            //Because the compiler doesn't know that it will have a value - Julian
            Side     leftRight;
            Halfedge lbnd, rbnd, llbnd, rrbnd, bisector;
            Edge     edge;

            Rect dataBounds = _sites.GetSitesBounds();

            int sqrt_nsites            = (int)(Mathf.Sqrt(_sites.Count + 4));
            HalfedgePriorityQueue heap = new HalfedgePriorityQueue(dataBounds.y, dataBounds.height, sqrt_nsites);
            EdgeList        edgeList   = new EdgeList(dataBounds.x, dataBounds.width, sqrt_nsites);
            List <Halfedge> halfEdges  = new List <Halfedge> ();
            List <Vertex>   vertices   = new List <Vertex> ();

            fortunesAlgorithm_bottomMostSite = _sites.Next();
            newSite = _sites.Next();

            for (;;)
            {
                if (heap.Empty() == false)
                {
                    newintstar = heap.Min();
                }

                if (newSite != null &&
                    (heap.Empty() || CompareByYThenX(newSite, newintstar) < 0))
                {
                    /* new site is smallest */
                    //trace("smallest: new site " + newSite);

                    // Step 8:
                    lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord);                // the Halfedge just to the left of newSite
                    //trace("lbnd: " + lbnd);
                    rbnd = lbnd.edgeListRightNeighbor;                                  // the Halfedge just to the right
                    //trace("rbnd: " + rbnd);
                    bottomSite = FortunesAlgorithm_rightRegion(lbnd);                   // 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.Dist(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.Dist(vertex);
                        heap.Insert(bisector);
                    }

                    newSite = _sites.Next();
                }
                else if (heap.Empty() == false)
                {
                    /* intersection is smallest */
                    lbnd       = heap.ExtractMin();
                    llbnd      = lbnd.edgeListLeftNeighbor;
                    rbnd       = lbnd.edgeListRightNeighbor;
                    rrbnd      = rbnd.edgeListRightNeighbor;
                    bottomSite = FortunesAlgorithm_leftRegion(lbnd);
                    topSite    = FortunesAlgorithm_rightRegion(rbnd);
                    // these three sites define a Delaunay triangle
                    // (not actually using these for anything...)
                    // ******ADDED******
                    _triangles.Add(new Triangle(bottomSite, topSite, FortunesAlgorithm_rightRegion(lbnd)));

                    v = lbnd.vertex;
                    v.SetIndex();
                    lbnd.edge.SetVertex((Side)lbnd.leftRight, v);
                    rbnd.edge.SetVertex((Side)rbnd.leftRight, v);
                    edgeList.Remove(lbnd);
                    heap.Remove(rbnd);
                    edgeList.Remove(rbnd);
                    leftRight = Side.LEFT;
                    if (bottomSite.y > topSite.y)
                    {
                        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.Dist(vertex);
                        heap.Insert(llbnd);
                    }
                    if ((vertex = Vertex.Intersect(bisector, rrbnd)) != null)
                    {
                        vertices.Add(vertex);
                        bisector.vertex = vertex;
                        bisector.ystar  = vertex.y + bottomSite.Dist(vertex);
                        heap.Insert(bisector);
                    }
                }
                else
                {
                    break;
                }
            }

            // heap should be empty now
            heap.Dispose();
            edgeList.Dispose();

            for (int hIndex = 0; hIndex < halfEdges.Count; hIndex++)
            {
                Halfedge halfEdge = halfEdges [hIndex];
                halfEdge.ReallyDispose();
            }
            halfEdges.Clear();

            // we need the vertices to clip the edges
            for (int eIndex = 0; eIndex < _edges.Count; eIndex++)
            {
                edge = _edges [eIndex];
                edge.ClipVertices(_plotBounds);
            }
            // but we don't actually ever use them again!
            for (int vIndex = 0; vIndex < vertices.Count; vIndex++)
            {
                vertex = vertices [vIndex];
                vertex.Dispose();
            }
            vertices.Clear();
        }
Пример #4
0
        private void FortunesAlgorithm()
        {
            Site     newSite, bottomSite, topSite, tempSite;
            Vertex   v, vertex;
            Vector2f newIntStar = Vector2f.zero;
            LR       leftRight;
            Halfedge lbnd, rbnd, llbnd, rrbnd, bisector;
            Edge     edge;

            Rectf dataBounds = sites.GetSitesBounds();

            int sqrtSitesNb            = (int)Math.Sqrt(sites.Count() + 4);
            HalfedgePriorityQueue heap = new HalfedgePriorityQueue(dataBounds.y, dataBounds.height, sqrtSitesNb);
            EdgeList        edgeList   = new EdgeList(dataBounds.x, dataBounds.width, sqrtSitesNb);
            List <Halfedge> halfEdges  = new List <Halfedge>();
            List <Vertex>   vertices   = new List <Vertex>();

            Site bottomMostSite = sites.Next();

            newSite = sites.Next();

            while (true)
            {
                if (!heap.Empty())
                {
                    newIntStar = heap.Min();
                }

                if (newSite != null &&
                    (heap.Empty() || CompareByYThenX(newSite, newIntStar) < 0))
                {
                    // New site is smallest
                    //Debug.Log("smallest: new site " + newSite);

                    // Step 8:
                    lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord); // The halfedge just to the left of newSite
                                                                         //UnityEngine.Debug.Log("lbnd: " + lbnd);
                    rbnd = lbnd.edgeListRightNeighbor;                   // The halfedge just to the right
                                                                         //UnityEngine.Debug.Log("rbnd: " + rbnd);
                    bottomSite = RightRegion(lbnd, bottomMostSite);      // This is the same as leftRegion(rbnd)
                                                                         // This Site determines the region containing the new site
                                                                         //UnityEngine.Debug.Log("new Site is in region of existing site: " + bottomSite);

                    // Step 9
                    edge = Edge.CreateBisectingEdge(bottomSite, newSite);
                    //UnityEngine.Debug.Log("new edge: " + edge);
                    edges.Add(edge);

                    bisector = Halfedge.Create(edge, LR.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.Dist(vertex);
                        heap.Insert(lbnd);
                    }

                    lbnd     = bisector;
                    bisector = Halfedge.Create(edge, LR.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.Dist(vertex);
                        heap.Insert(bisector);
                    }

                    newSite = sites.Next();
                }
                else if (!heap.Empty())
                {
                    // Intersection is smallest
                    lbnd       = heap.ExtractMin();
                    llbnd      = lbnd.edgeListLeftNeighbor;
                    rbnd       = lbnd.edgeListRightNeighbor;
                    rrbnd      = rbnd.edgeListRightNeighbor;
                    bottomSite = LeftRegion(lbnd, bottomMostSite);
                    topSite    = RightRegion(rbnd, bottomMostSite);
                    // These three sites define a Delaunay triangle
                    // (not actually using these for anything...)
                    // triangles.Add(new Triangle(bottomSite, topSite, RightRegion(lbnd, bottomMostSite)));

                    v = lbnd.vertex;
                    v.SetIndex();
                    lbnd.edge.SetVertex(lbnd.leftRight, v);
                    rbnd.edge.SetVertex(rbnd.leftRight, v);
                    edgeList.Remove(lbnd);
                    heap.Remove(rbnd);
                    edgeList.Remove(rbnd);
                    leftRight = LR.LEFT;
                    if (bottomSite.y > topSite.y)
                    {
                        tempSite   = bottomSite;
                        bottomSite = topSite;
                        topSite    = tempSite;
                        leftRight  = LR.RIGHT;
                    }
                    edge = Edge.CreateBisectingEdge(bottomSite, topSite);
                    edges.Add(edge);
                    bisector = Halfedge.Create(edge, leftRight);
                    halfEdges.Add(bisector);
                    edgeList.Insert(llbnd, bisector);
                    edge.SetVertex(LR.Other(leftRight), v);
                    if ((vertex = Vertex.Intersect(llbnd, bisector)) != null)
                    {
                        vertices.Add(vertex);
                        heap.Remove(llbnd);
                        llbnd.vertex = vertex;
                        llbnd.ystar  = vertex.y + bottomSite.Dist(vertex);
                        heap.Insert(llbnd);
                    }
                    if ((vertex = Vertex.Intersect(bisector, rrbnd)) != null)
                    {
                        vertices.Add(vertex);
                        bisector.vertex = vertex;
                        bisector.ystar  = vertex.y + bottomSite.Dist(vertex);
                        heap.Insert(bisector);
                    }
                }
                else
                {
                    break;
                }
            }

            // Heap should be empty now
            heap.Dispose();
            edgeList.Dispose();

            foreach (Halfedge halfedge in halfEdges)
            {
                halfedge.ReallyDispose();
            }
            halfEdges.Clear();

            // we need the vertices to clip the edges
            foreach (Edge e in edges)
            {
                e.ClipVertices(plotBounds);
            }
            // But we don't actually ever use them again!
            foreach (Vertex ve in vertices)
            {
                ve.Dispose();
            }
            vertices.Clear();
        }
Пример #5
0
        private void FortunesAlgorithm()
        {
            Vector2 s           = Vector2.zero;
            Rect    sitesBounds = _sites.GetSitesBounds();
            int     sqrt_nsites = (int)Mathf.Sqrt(_sites.Count + 4);
            HalfedgePriorityQueue halfedgePriorityQueue = new HalfedgePriorityQueue(sitesBounds.y, sitesBounds.height, sqrt_nsites);
            EdgeList        edgeList = new EdgeList(sitesBounds.x, sitesBounds.width, sqrt_nsites);
            List <Halfedge> list     = new List <Halfedge>();
            List <Vertex>   list2    = new List <Vertex>();

            fortunesAlgorithm_bottomMostSite = _sites.Next();
            Site site = _sites.Next();

            while (true)
            {
                if (!halfedgePriorityQueue.Empty())
                {
                    s = halfedgePriorityQueue.Min();
                }
                if (site != null && (halfedgePriorityQueue.Empty() || CompareByYThenX(site, s) < 0))
                {
                    Halfedge halfedge = edgeList.EdgeListLeftNeighbor(site.Coord);
                    Halfedge edgeListRightNeighbor = halfedge.edgeListRightNeighbor;
                    Site     site2 = FortunesAlgorithm_rightRegion(halfedge);
                    Edge     edge  = Edge.CreateBisectingEdge(site2, site);
                    _edges.Add(edge);
                    Halfedge halfedge2 = Halfedge.Create(edge, Side.LEFT);
                    list.Add(halfedge2);
                    edgeList.Insert(halfedge, halfedge2);
                    Vertex vertex;
                    if ((vertex = Vertex.Intersect(halfedge, halfedge2)) != null)
                    {
                        list2.Add(vertex);
                        halfedgePriorityQueue.Remove(halfedge);
                        halfedge.vertex = vertex;
                        halfedge.ystar  = vertex.y + site.Dist(vertex);
                        halfedgePriorityQueue.Insert(halfedge);
                    }
                    halfedge  = halfedge2;
                    halfedge2 = Halfedge.Create(edge, Side.RIGHT);
                    list.Add(halfedge2);
                    edgeList.Insert(halfedge, halfedge2);
                    if ((vertex = Vertex.Intersect(halfedge2, edgeListRightNeighbor)) != null)
                    {
                        list2.Add(vertex);
                        halfedge2.vertex = vertex;
                        halfedge2.ystar  = vertex.y + site.Dist(vertex);
                        halfedgePriorityQueue.Insert(halfedge2);
                    }
                    site = _sites.Next();
                    continue;
                }
                if (!halfedgePriorityQueue.Empty())
                {
                    Halfedge halfedge               = halfedgePriorityQueue.ExtractMin();
                    Halfedge edgeListLeftNeighbor   = halfedge.edgeListLeftNeighbor;
                    Halfedge edgeListRightNeighbor  = halfedge.edgeListRightNeighbor;
                    Halfedge edgeListRightNeighbor2 = edgeListRightNeighbor.edgeListRightNeighbor;
                    Site     site2 = FortunesAlgorithm_leftRegion(halfedge);
                    Site     site3 = FortunesAlgorithm_rightRegion(edgeListRightNeighbor);
                    _triangles.Add(new Triangle(site2, site3, FortunesAlgorithm_rightRegion(halfedge)));
                    Vertex vertex2 = halfedge.vertex;
                    vertex2.SetIndex();
                    Edge edge2     = halfedge.edge;
                    Side?leftRight = halfedge.leftRight;
                    edge2.SetVertex(leftRight.Value, vertex2);
                    Edge edge3      = edgeListRightNeighbor.edge;
                    Side?leftRight2 = edgeListRightNeighbor.leftRight;
                    edge3.SetVertex(leftRight2.Value, vertex2);
                    edgeList.Remove(halfedge);
                    halfedgePriorityQueue.Remove(edgeListRightNeighbor);
                    edgeList.Remove(edgeListRightNeighbor);
                    Side side = Side.LEFT;
                    if (site2.y > site3.y)
                    {
                        Site site4 = site2;
                        site2 = site3;
                        site3 = site4;
                        side  = Side.RIGHT;
                    }
                    Edge edge = Edge.CreateBisectingEdge(site2, site3);
                    _edges.Add(edge);
                    Halfedge halfedge2 = Halfedge.Create(edge, side);
                    list.Add(halfedge2);
                    edgeList.Insert(edgeListLeftNeighbor, halfedge2);
                    edge.SetVertex(SideHelper.Other(side), vertex2);
                    Vertex vertex;
                    if ((vertex = Vertex.Intersect(edgeListLeftNeighbor, halfedge2)) != null)
                    {
                        list2.Add(vertex);
                        halfedgePriorityQueue.Remove(edgeListLeftNeighbor);
                        edgeListLeftNeighbor.vertex = vertex;
                        edgeListLeftNeighbor.ystar  = vertex.y + site2.Dist(vertex);
                        halfedgePriorityQueue.Insert(edgeListLeftNeighbor);
                    }
                    if ((vertex = Vertex.Intersect(halfedge2, edgeListRightNeighbor2)) != null)
                    {
                        list2.Add(vertex);
                        halfedge2.vertex = vertex;
                        halfedge2.ystar  = vertex.y + site2.Dist(vertex);
                        halfedgePriorityQueue.Insert(halfedge2);
                    }
                    continue;
                }
                break;
            }
            halfedgePriorityQueue.Dispose();
            edgeList.Dispose();
            for (int i = 0; i < list.Count; i++)
            {
                Halfedge halfedge3 = list[i];
                halfedge3.ReallyDispose();
            }
            list.Clear();
            for (int j = 0; j < _edges.Count; j++)
            {
                Edge edge = _edges[j];
                edge.ClipVertices(_plotBounds);
            }
            for (int k = 0; k < list2.Count; k++)
            {
                Vertex vertex = list2[k];
                vertex.Dispose();
            }
            list2.Clear();
        }
Пример #6
0
        private void FortunesAlgorithm()
        {
            Site newSite, bottomSite, topSite, tempSite;
            Vertex v, vertex;
            PointF newintstar = PointF.Empty;
            LR leftRight;
            Halfedge lbnd, rbnd, llbnd, rrbnd, bisector;
            Edge edge;

            RectangleF dataBounds = _sites.GetSitesBounds();

            int sqrt_nsites = (int)(Math.Sqrt(_sites.Length + 4));
            HalfedgePriorityQueue heap = new HalfedgePriorityQueue(dataBounds.Y, dataBounds.Height, sqrt_nsites);
            EdgeList edgeList = new EdgeList(dataBounds.X, dataBounds.Width, sqrt_nsites);
            List<Halfedge> halfEdges = new List<Halfedge>();
            List<Vertex> vertices = new List<Vertex>();

            Site bottomMostSite = _sites.Next();
            newSite = _sites.Next();

            for (; ; )
            {
                if (heap.Empty() == false)
                {
                    newintstar = heap.Min();
                }

                if (newSite != null
                && (heap.Empty() || CompareByYThenX(newSite, newintstar) < 0))
                {
                    /* new site is smallest */
                    //trace("smallest: new site " + newSite);

                    // Step 8:
                    lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord());	// 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, LR.LEFT);
                    halfEdges.Add(bisector);
                    // inserting two Halfedges into edgeList static readonlyitutes 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.Dist(vertex);
                        heap.Insert(lbnd);
                    }

                    lbnd = bisector;
                    bisector = Halfedge.Create(edge, LR.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.Dist(vertex);
                        heap.Insert(bisector);
                    }

                    newSite = _sites.Next();
                }
                else if (heap.Empty() == false)
                {
                    /* intersection is smallest */
                    lbnd = heap.ExtractMin();
                    llbnd = lbnd.edgeListLeftNeighbor;
                    rbnd = lbnd.edgeListRightNeighbor;
                    rrbnd = rbnd.edgeListRightNeighbor;
                    bottomSite = LeftRegion(lbnd, bottomMostSite);
                    topSite = RightRegion(rbnd, bottomMostSite);
                    // these three sites define a Delaunay triangle
                    // (not actually using these for anything...)
                    //_triangles.Add(new Triangle(bottomSite, topSite, rightRegion(lbnd)));

                    v = lbnd.vertex;
                    v.SetIndex();
                    lbnd.edge.SetVertex(lbnd.leftRight, v);
                    rbnd.edge.SetVertex(rbnd.leftRight, v);
                    edgeList.Remove(lbnd);
                    heap.Remove(rbnd);
                    edgeList.Remove(rbnd);
                    leftRight = LR.LEFT;
                    if (bottomSite.Y > topSite.Y)
                    {
                        tempSite = bottomSite; bottomSite = topSite; topSite = tempSite; leftRight = LR.RIGHT;
                    }
                    edge = Edge.CreateBisectingEdge(bottomSite, topSite);
                    _edges.Add(edge);
                    bisector = Halfedge.Create(edge, leftRight);
                    halfEdges.Add(bisector);
                    edgeList.Insert(llbnd, bisector);
                    edge.SetVertex(LR.Other(leftRight), v);
                    if ((vertex = Vertex.Intersect(llbnd, bisector)) != null)
                    {
                        vertices.Add(vertex);
                        heap.Remove(llbnd);
                        llbnd.vertex = vertex;
                        llbnd.ystar = vertex.Y + bottomSite.Dist(vertex);
                        heap.Insert(llbnd);
                    }
                    if ((vertex = Vertex.Intersect(bisector, rrbnd)) != null)
                    {
                        vertices.Add(vertex);
                        bisector.vertex = vertex;
                        bisector.ystar = vertex.Y + bottomSite.Dist(vertex);
                        heap.Insert(bisector);
                    }
                }
                else
                {
                    break;
                }
            }

            // heap should be empty now
            heap.Dispose();
            edgeList.Dispose();

            foreach (Halfedge halfEdge in halfEdges)
            {
                halfEdge.ReallyDispose();
            }
            halfEdges.Clear();

            // we need the vertices to clip the edges
            foreach (Edge edge2 in _edges)
            {
                edge2.ClipVertices(_plotBounds);
            }
            // but we don't actually ever use them again!
            foreach (Vertex vertex2 in vertices)
            {
                vertex2.Dispose();
            }
            vertices.Clear();
        }