コード例 #1
0
ファイル: Vertex.cs プロジェクト: remy22/dx11
        public static Vertex Intersect(HalfEdge he0, HalfEdge he1)
        {
            var edge0 = he0.Edge;
            var edge1 = he1.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) {
                return null;
            }
            var intersectionX = (edge0.C*edge1.B - edge1.C*edge0.B)/determinant;
            var intersectionY = (edge1.C*edge0.A - edge0.C * edge1.A)/determinant;

            HalfEdge halfEdge;
            Edge edge;
            if (Voronoi.CompareByYThenX(edge0.RightSite, edge1.RightSite) < 0) {
                halfEdge = he0;
                edge = edge0;
            } else {
                halfEdge = he1;
                edge = edge1;
            }
            var rightOfSite = intersectionX >= edge.RightSite.X;
            if ((rightOfSite && halfEdge.LeftRight == LR.Left) || (!rightOfSite && halfEdge.LeftRight == LR.Right)) {
                return null;
            }
            return Create(intersectionX, intersectionY);
        }
コード例 #2
0
ファイル: HalfEdgePriorityQueue.cs プロジェクト: remy22/dx11
 public void Remove(HalfEdge halfEdge)
 {
     var removalBucket = Bucket(halfEdge);
     if (halfEdge.Vertex != null) {
         var previous = _hash[removalBucket];
         while (previous.NextInPriorityQueue != halfEdge) {
             previous = previous.NextInPriorityQueue;
         }
         previous.NextInPriorityQueue = halfEdge.NextInPriorityQueue;
         _count--;
     }
 }
コード例 #3
0
ファイル: HalfEdgePriorityQueue.cs プロジェクト: remy22/dx11
 public void Insert(HalfEdge halfEdge)
 {
     var insertionBucket = Bucket(halfEdge);
     if (insertionBucket < _minBucket) {
         _minBucket = insertionBucket;
     }
     var previous = _hash[insertionBucket];
     HalfEdge next;
     while ((next = previous.NextInPriorityQueue) != null && (halfEdge.YStar > next.YStar && halfEdge.Vertex.X > next.Vertex.X)) {
         previous = next;
     }
     halfEdge.NextInPriorityQueue = previous.NextInPriorityQueue;
     previous.NextInPriorityQueue = halfEdge;
     ++_count;
 }
コード例 #4
0
ファイル: EdgeList.cs プロジェクト: remy22/dx11
        public EdgeList(float xmin, float deltax, int sqrtNSites)
        {
            _xmin = xmin;
            _deltaX = deltax;
            _hashSize = 2 * sqrtNSites;

            _hash = new List<HalfEdge>(new HalfEdge[_hashSize]);

            LeftEnd = new HalfEdge();
            RightEnd = new HalfEdge();
            LeftEnd.EdgeListLeftNeighbor = null;
            LeftEnd.EdgeListRightNeighbor = RightEnd;
            RightEnd.EdgeListLeftNeighbor = LeftEnd;
            RightEnd.EdgeListRightNeighbor = null;
            _hash[0] = LeftEnd;
            _hash[_hashSize - 1] = RightEnd;
        }
コード例 #5
0
ファイル: Voronoi.cs プロジェクト: remy22/dx11
 private static Site RightRegion(HalfEdge he)
 {
     var edge = he.Edge;
     return edge == null ? null : edge.Site(LR.Other(he.LeftRight));
 }
コード例 #6
0
ファイル: Voronoi.cs プロジェクト: remy22/dx11
        private void FortunesAlgorithm()
        {
            var dataBounds = _sites.GetSiteBounds();
            var sqrtNSites = (int)Math.Sqrt(_sites.Length + 4);
            var heap = new HalfEdgePriorityQueue(dataBounds.Top, dataBounds.Height, sqrtNSites);
            var edgeList = new EdgeList(dataBounds.Left, dataBounds.Width, sqrtNSites);
            var halfEdges = new List<HalfEdge>();
            var vertices = new List<Vertex>();

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

            var newIntStar = new Vector2();

            for (; ; ) {
                if (!heap.Empty) {
                    newIntStar = heap.Min();
                }
                if (newSite != null && (heap.Empty || CompareByYThenX(newSite, newIntStar) < 0)) {
                    Console.WriteLine("smallest: new site " + newSite);
                    var lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord);
                    Console.WriteLine("lbnd: " + lbnd);
                    var rbnd = lbnd.EdgeListRightNeighbor;
                    Console.WriteLine("rbnd: " + rbnd);
                    var bottomSite = RightRegion(lbnd) ?? bottomMostSite;
                    Console.WriteLine("new site is in region of existing site: " + bottomSite);

                    var edge = Edge.CreateBisectingEdge(bottomSite, newSite);
                    Console.WriteLine("new edge: " + edge);
                    Edges.Add(edge);

                    var bisector = new HalfEdge(edge, LR.Left);
                    halfEdges.Add(bisector);

                    edgeList.Insert(lbnd, bisector);

                    Vertex vertex = Vertex.Intersect(lbnd, bisector);
                    if (vertex != null) {
                        vertices.Add(vertex);
                        heap.Remove(lbnd);
                        lbnd.Vertex = vertex;
                        lbnd.YStar = vertex.Y + newSite.Distance(vertex);
                        heap.Insert(lbnd);
                    }
                    lbnd = bisector;
                    bisector = new HalfEdge(edge, LR.Right);
                    halfEdges.Add(bisector);

                    edgeList.Insert(lbnd, bisector);
                    vertex = Vertex.Intersect(bisector, rbnd);
                    if (vertex != null) {
                        vertices.Add(vertex);
                        bisector.Vertex = vertex;
                        bisector.YStar = vertex.Y + newSite.Distance(vertex);
                        heap.Insert(bisector);
                    }
                    newSite = _sites.Next();
                } else if (!heap.Empty) {
                    var lbnd = heap.ExtractMin();
                    var llbnd = lbnd.EdgeListLeftNeighbor;
                    var rbnd = lbnd.EdgeListRightNeighbor;
                    var rrbnd = rbnd.EdgeListRightNeighbor;
                    var bottomSite = LeftRegion(lbnd) ?? bottomMostSite;
                    var topSite = RightRegion(rbnd) ?? bottomMostSite;

                    var 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);
                    var leftRight = LR.Left;
                    if (bottomSite.Y > topSite.Y) {
                        var tempSite = bottomSite;
                        bottomSite = topSite;
                        topSite = tempSite;
                        leftRight = LR.Right;
                    }
                    var edge = Edge.CreateBisectingEdge(bottomSite, topSite);
                    Edges.Add(edge);
                    var bisector = new HalfEdge(edge, leftRight);
                    halfEdges.Add(bisector);
                    edgeList.Insert(llbnd, bisector);

                    edge.SetVertex(LR.Other(leftRight), v);

                    Vertex vertex;
                    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;
                }
            }
            halfEdges.Clear();

            var nullVerts = Edges.Where(e => e.RightVertex == null || e.LeftVertex == null).ToList();

            foreach (var edge in Edges) {
                edge.ClipVertices(PlotBounds);
            }
            vertices.Clear();
        }
コード例 #7
0
        private void FortunesAlgorithm()
        {
            var dataBounds = _sites.GetSiteBounds();
            var sqrtNSites = (int)Math.Sqrt(_sites.Length + 4);
            var heap       = new HalfEdgePriorityQueue(dataBounds.Top, dataBounds.Height, sqrtNSites);
            var edgeList   = new EdgeList(dataBounds.Left, dataBounds.Width, sqrtNSites);
            var halfEdges  = new List <HalfEdge>();
            var vertices   = new List <Vertex>();

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

            var newIntStar = new Vector2();

            for (; ;)
            {
                if (!heap.Empty)
                {
                    newIntStar = heap.Min();
                }
                if (newSite != null && (heap.Empty || CompareByYThenX(newSite, newIntStar) < 0))
                {
                    Console.WriteLine("smallest: new site " + newSite);
                    var lbnd = edgeList.EdgeListLeftNeighbor(newSite.Coord);
                    Console.WriteLine("lbnd: " + lbnd);
                    var rbnd = lbnd.EdgeListRightNeighbor;
                    Console.WriteLine("rbnd: " + rbnd);
                    var bottomSite = RightRegion(lbnd) ?? bottomMostSite;
                    Console.WriteLine("new site is in region of existing site: " + bottomSite);

                    var edge = Edge.CreateBisectingEdge(bottomSite, newSite);
                    Console.WriteLine("new edge: " + edge);
                    Edges.Add(edge);

                    var bisector = new HalfEdge(edge, LR.Left);
                    halfEdges.Add(bisector);

                    edgeList.Insert(lbnd, bisector);

                    Vertex vertex = Vertex.Intersect(lbnd, bisector);
                    if (vertex != null)
                    {
                        vertices.Add(vertex);
                        heap.Remove(lbnd);
                        lbnd.Vertex = vertex;
                        lbnd.YStar  = vertex.Y + newSite.Distance(vertex);
                        heap.Insert(lbnd);
                    }
                    lbnd     = bisector;
                    bisector = new HalfEdge(edge, LR.Right);
                    halfEdges.Add(bisector);

                    edgeList.Insert(lbnd, bisector);
                    vertex = Vertex.Intersect(bisector, rbnd);
                    if (vertex != null)
                    {
                        vertices.Add(vertex);
                        bisector.Vertex = vertex;
                        bisector.YStar  = vertex.Y + newSite.Distance(vertex);
                        heap.Insert(bisector);
                    }
                    newSite = _sites.Next();
                }
                else if (!heap.Empty)
                {
                    var lbnd       = heap.ExtractMin();
                    var llbnd      = lbnd.EdgeListLeftNeighbor;
                    var rbnd       = lbnd.EdgeListRightNeighbor;
                    var rrbnd      = rbnd.EdgeListRightNeighbor;
                    var bottomSite = LeftRegion(lbnd) ?? bottomMostSite;
                    var topSite    = RightRegion(rbnd) ?? bottomMostSite;

                    var 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);
                    var leftRight = LR.Left;
                    if (bottomSite.Y > topSite.Y)
                    {
                        var tempSite = bottomSite;
                        bottomSite = topSite;
                        topSite    = tempSite;
                        leftRight  = LR.Right;
                    }
                    var edge = Edge.CreateBisectingEdge(bottomSite, topSite);
                    Edges.Add(edge);
                    var bisector = new HalfEdge(edge, leftRight);
                    halfEdges.Add(bisector);
                    edgeList.Insert(llbnd, bisector);

                    edge.SetVertex(LR.Other(leftRight), v);

                    Vertex vertex;
                    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;
                }
            }
            halfEdges.Clear();


            var nullVerts = Edges.Where(e => e.RightVertex == null || e.LeftVertex == null).ToList();

            foreach (var edge in Edges)
            {
                edge.ClipVertices(PlotBounds);
            }
            vertices.Clear();
        }
コード例 #8
0
        private static Site RightRegion(HalfEdge he)
        {
            var edge = he.Edge;

            return(edge == null ? null : edge.Site(LR.Other(he.LeftRight)));
        }
コード例 #9
0
ファイル: HalfEdge.cs プロジェクト: remy22/dx11
 private void Init(Edge edge, LR lr)
 {
     Edge = edge;
     LeftRight = lr;
     NextInPriorityQueue = null;
     Vertex = null;
 }
コード例 #10
0
ファイル: HalfEdgePriorityQueue.cs プロジェクト: remy22/dx11
 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;
 }
コード例 #11
0
ファイル: HalfEdgePriorityQueue.cs プロジェクト: remy22/dx11
 private void Initialize()
 {
     _count = 0;
     _minBucket = 0;
     _hash = new List<HalfEdge>(new HalfEdge[_hashSize]);
     for (int i = 0; i < _hashSize; i++) {
         _hash[i] = new HalfEdge {
             NextInPriorityQueue = null
         };
     }
 }
コード例 #12
0
ファイル: HalfEdge.cs プロジェクト: mrommel/dx11
 private void Init(Edge edge, LR lr) {
     Edge = edge;
     LeftRight = lr;
     NextInPriorityQueue = null;
     Vertex = null;
 }
コード例 #13
0
ファイル: EdgeList.cs プロジェクト: remy22/dx11
 public void Remove(HalfEdge halfEdge)
 {
     halfEdge.EdgeListLeftNeighbor.EdgeListRightNeighbor = halfEdge.EdgeListRightNeighbor;
     halfEdge.EdgeListRightNeighbor.EdgeListLeftNeighbor = halfEdge.EdgeListLeftNeighbor;
     halfEdge.Edge = Edge.Deleted;
     halfEdge.EdgeListLeftNeighbor = halfEdge.EdgeListRightNeighbor = null;
 }
コード例 #14
0
ファイル: EdgeList.cs プロジェクト: remy22/dx11
 public void Insert(HalfEdge lb, HalfEdge newHalfEdge)
 {
     newHalfEdge.EdgeListLeftNeighbor = lb;
     newHalfEdge.EdgeListRightNeighbor = lb.EdgeListRightNeighbor;
     lb.EdgeListRightNeighbor.EdgeListLeftNeighbor = newHalfEdge;
     lb.EdgeListRightNeighbor = newHalfEdge;
 }