Beispiel #1
0
        public HalfEdge Init(Edge edge, Side? side)
        {
            Edge = edge;
            LeftOrRight = side;
            NextInPriorityQueue = null;
            Vertex = null;

            return this;
        }
Beispiel #2
0
 public void ReallyDispose()
 {
     EdgeListLeftNeighbor = null;
     EdgeListRightNeighbor = null;
     NextInPriorityQueue = null;
     Edge = null;
     LeftOrRight = null;
     Vertex = null;
     pool.Push(this);
 }
Beispiel #3
0
        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++;
        }
Beispiel #5
0
        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;
        }
Beispiel #6
0
 public void Remove(HalfEdge halfEdge)
 {
     halfEdge.EdgeListLeftNeighbor.EdgeListRightNeighbor = halfEdge.EdgeListRightNeighbor;
     halfEdge.EdgeListRightNeighbor.EdgeListLeftNeighbor = halfEdge.EdgeListLeftNeighbor;
     halfEdge.Edge = Edge.Deleted;
     halfEdge.EdgeListLeftNeighbor = halfEdge.EdgeListRightNeighbor = null;
 }
Beispiel #7
0
        public void Insert(HalfEdge lb, HalfEdge newHalfEdge)
        {
            newHalfEdge.EdgeListLeftNeighbor = lb;
            newHalfEdge.EdgeListRightNeighbor = lb.EdgeListRightNeighbor;

            lb.EdgeListRightNeighbor.EdgeListLeftNeighbor = newHalfEdge;
            lb.EdgeListRightNeighbor = newHalfEdge;
        }
Beispiel #8
0
 private static Site RightRegion(HalfEdge halfEdge, Site bottomMostSite)
 {
     var edge = halfEdge.Edge;
     return edge == null ? bottomMostSite : edge.Site(SideHelper.Other((Side)halfEdge.LeftOrRight));
 }
Beispiel #9
0
        private static Site RightRegion(HalfEdge halfEdge, Site bottomMostSite)
        {
            var edge = halfEdge.Edge;

            return(edge == null ? bottomMostSite : edge.Site(SideHelper.Other((Side)halfEdge.LeftOrRight)));
        }
Beispiel #10
0
        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;
 }