Beispiel #1
0
        private List <Vector2> ClipToBounds(Rectangle bounds)
        {
            var points = new List <Vector2>();
            var n      = Edges.Count;
            var i      = 0;

            while (i < n && (!(Edges[i]).Visible))
            {
                i++;
            }
            if (i == n)
            {
                return(new List <Vector2>());
            }
            var edge        = Edges[i];
            var orientation = _edgeOrientations[i];

            points.Add(edge.ClippedEnds[orientation]);
            points.Add(edge.ClippedEnds[LR.Other(orientation)]);

            for (int j = i; j < n; j++)
            {
                edge = Edges[j];
                if (edge.Visible)
                {
                    Connect(points, j, bounds);
                }
            }
            Connect(points, i, bounds, true);
            return(points);
        }
Beispiel #2
0
 public void SetVertex(LR leftRight, Vertex v)
 {
     if (leftRight == LR.Left)
     {
         _leftVertex = v;
     }
     else
     {
         _rightVertex = v;
     }
 }
Beispiel #3
0
        private void Connect(List <Vector2> points, int j, Rectangle bounds, bool closingUp = false)
        {
            var rightPoint     = points.Last();
            var newEdge        = Edges[j];
            var newOrientation = _edgeOrientations[j];
            var newPoint       = newEdge.ClippedEnds[newOrientation];

            if (!CloseEnough(rightPoint, newPoint))
            {
                if (!Equals(rightPoint.X, newPoint.X) && !Equals(rightPoint.Y, newPoint.Y))
                {
                    var   rightCheck = BoundsChecker.Check(rightPoint, bounds);
                    var   newCheck = BoundsChecker.Check(newPoint, bounds);
                    float px, py;
                    if (rightCheck.HasFlag(BoundsCheck.Right))
                    {
                        px = bounds.Right;
                        if (newCheck.HasFlag(BoundsCheck.Bottom))
                        {
                            py = bounds.Bottom;
                            points.Add(new Vector2(px, py));
                        }
                        else if (newCheck.HasFlag(BoundsCheck.Top))
                        {
                            py = bounds.Top;
                            points.Add(new Vector2(px, py));
                        }
                        else if (newCheck.HasFlag(BoundsCheck.Left))
                        {
                            py = rightPoint.Y - bounds.Top + newPoint.Y - bounds.Top < bounds.Height ? bounds.Top : bounds.Bottom;
                            points.Add(new Vector2(px, py));
                            points.Add(new Vector2(bounds.Left, py));
                        }
                    }
                    else if (rightCheck.HasFlag(BoundsCheck.Left))
                    {
                        px = bounds.Left;
                        if (newCheck.HasFlag(BoundsCheck.Bottom))
                        {
                            py = bounds.Bottom;
                            points.Add(new Vector2(px, py));
                        }
                        else if (newCheck.HasFlag(BoundsCheck.Top))
                        {
                            py = bounds.Top;
                            points.Add(new Vector2(px, py));
                        }
                        else if (newCheck.HasFlag(BoundsCheck.Right))
                        {
                            py = rightPoint.Y - bounds.Top + newPoint.Y - bounds.Top < bounds.Height ? bounds.Top : bounds.Bottom;
                            points.Add(new Vector2(px, py));
                            points.Add(new Vector2(bounds.Right, py));
                        }
                    }
                    else if (rightCheck.HasFlag(BoundsCheck.Top))
                    {
                        py = bounds.Top;
                        if (newCheck.HasFlag(BoundsCheck.Right))
                        {
                            px = bounds.Right;
                            points.Add(new Vector2(px, py));
                        }
                        else if (newCheck.HasFlag(BoundsCheck.Left))
                        {
                            px = bounds.Left;
                            points.Add(new Vector2(px, py));
                        }
                        else if (newCheck.HasFlag(BoundsCheck.Bottom))
                        {
                            px = rightPoint.X - bounds.Left + newPoint.X - bounds.Left < bounds.Width ? bounds.Left : bounds.Right;
                            points.Add(new Vector2(px, py));
                            points.Add(new Vector2(px, bounds.Bottom));
                        }
                    }
                    else if (rightCheck.HasFlag(BoundsCheck.Bottom))
                    {
                        py = bounds.Bottom;
                        if (newCheck.HasFlag(BoundsCheck.Right))
                        {
                            px = bounds.Right;
                            points.Add(new Vector2(px, py));
                        }
                        else if (newCheck.HasFlag(BoundsCheck.Left))
                        {
                            px = bounds.Left;
                            points.Add(new Vector2(px, py));
                        }
                        else if (newCheck.HasFlag(BoundsCheck.Top))
                        {
                            px = rightPoint.X - bounds.Left + newPoint.X - bounds.Left < bounds.Width ? bounds.Left : bounds.Right;
                            points.Add(new Vector2(px, py));
                            points.Add(new Vector2(px, bounds.Top));
                        }
                    }
                }
                if (closingUp)
                {
                    return;
                }
                points.Add(newPoint);
            }
            var newRightPoint = newEdge.ClippedEnds[LR.Other(newOrientation)];

            if (!CloseEnough(points[0], newRightPoint))
            {
                points.Add(newRightPoint);
            }
        }
Beispiel #4
0
 public Site Site(LR lr)
 {
     return _sites[lr];
 }
Beispiel #5
0
 public void SetVertex(LR leftRight, Vertex v)
 {
     if (leftRight == LR.Left) {
         _leftVertex = v;
     } else {
         _rightVertex = v;
     }
 }
Beispiel #6
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();
        }
Beispiel #7
0
        private static Site RightRegion(HalfEdge he)
        {
            var edge = he.Edge;

            return(edge == null ? null : edge.Site(LR.Other(he.LeftRight)));
        }
Beispiel #8
0
 private void Init(Edge edge, LR lr)
 {
     Edge = edge;
     LeftRight = lr;
     NextInPriorityQueue = null;
     Vertex = null;
 }
Beispiel #9
0
 public HalfEdge(Edge edge, LR lr)
 {
     Init(edge, lr);
 }
Beispiel #10
0
 private void Init(Edge edge, LR lr) {
     Edge = edge;
     LeftRight = lr;
     NextInPriorityQueue = null;
     Vertex = null;
 }
Beispiel #11
0
 public HalfEdge(Edge edge, LR lr) {
     Init(edge, lr);
 }
Beispiel #12
0
 public Site Site(LR lr)
 {
     return(_sites[lr]);
 }