示例#1
0
        void AddVoronoiCite(CdtTriangle triangle)
        {
            Point p;
            var goodTriangle = GetCenterOfDescribedCircle(triangle, out p);
            if (!goodTriangle)
                return;
            if (!BoundingBox.Contains(p))
                return;
            var rect=new Rectangle(p);
            rect.Pad(eps);
            if (voronoiSiteTree.GetAllIntersecting(rect).Count() > 0)
                return;

            voronoiSiteTree.Add(rect, p);
        }
        internal bool Run() {
            if (metroGraphData.Edges.Count() == 0) return false;

            var splittingPoints = new Dictionary<PointPair, List<Point>>();
            var treeOfVertices = new RTree<Point>();
            foreach (var vertex in Vertices()) {
                var r = new Rectangle(vertex.Point);
                r.Pad(ApproximateComparer.IntersectionEpsilon);
                treeOfVertices.Add(r, vertex.Point);
            }

            var treeOfEdges = RectangleNode<PointPair>.CreateRectangleNodeOnData(Edges(), e => new Rectangle(e.First, e.Second));
            RectangleNodeUtils.CrossRectangleNodes<PointPair>(treeOfEdges, treeOfEdges, (a, b) => IntersectTwoEdges(a, b, splittingPoints, treeOfVertices));

            SortInsertedPoints(splittingPoints);
            bool pointsInserted = InsertPointsIntoPolylines(splittingPoints);

            bool progress = FixPaths();

            bool pointsRemoved = RemoveUnimportantCrossings();

            return progress || pointsInserted || pointsRemoved;
        }
/*
        void AddSegsHandlingOverlaps(SymmetricTuple<int> seg, RTree<Point> tree, Point[] indexToPoints) {
            var overlaps = GetPointsOverlappingSeg(seg, tree,indexToPoints);
            if (overlaps.Count <= 2) {
                _segments.Insert(seg);
                return;
            }
            Point ep0 = indexToPoints[seg.A];
            AddSegment(ep0, overlaps[1]);
            AddSegment(overlaps[overlaps.Count - 2], indexToPoints[seg.B]);
            if (overlaps.Count > 3) {
                AddSegsHandlingOverlaps(new SymmetricTuple<int>(_pointIndices[overlaps[1]],_pointIndices[overlaps[overlaps.Count - 2]]), tree, indexToPoints);
            }
        }
*/

        List<Point> GetPointsOverlappingSeg(SymmetricTuple<int> seg, RTree<Point> tree, Point[] indexToPoints) {
            Point p0 = indexToPoints[seg.A];
            Point p1 = indexToPoints[seg.B];
            var rect = new Rectangle(p0, p1);
            rect.Pad(1e-5);

            Point[] vts = tree.GetAllIntersecting(rect).ToArray();

            double t;
            var vtsOverlapping = vts.Where(p => Point.DistToLineSegment(p, p0, p1, out t) < 1e-5).ToList();

            vtsOverlapping = vtsOverlapping.OrderBy(p => (p - p0).Length).ToList();
            if (vtsOverlapping.Count > 2) {
                Console.WriteLine("overlapping points");
                foreach (var v in vtsOverlapping)
                    Console.WriteLine(v);
            }
            return vtsOverlapping;
        }
 void CreateAndIndexBoundingBox() {
    _boundingBox = Rectangle.CreateAnEmptyBox();
     foreach(var p in _pointsToIndices.Keys) _boundingBox.Add(p);
     _boundingBox.Pad(1);
     IndexAPoint(_boundingBox.LeftBottom);
     IndexAPoint(_boundingBox.RightBottom);
     IndexAPoint(_boundingBox.LeftTop);
     IndexAPoint(_boundingBox.RightTop);
     //SplineRouter.ShowVisGraph(_visGraph, null, new[] { _boundingBox.Perimeter() }, null);
 }
        Point FindExistingVertexOrCreateNew(RTree<Point> tree, Point x) {
            var p = tree.RootNode.FirstHitNode(x);
            if (p != null)
                return p.UserData;

            var rect = new Rectangle(x);
            rect.Pad(ApproximateComparer.IntersectionEpsilon);
            tree.Add(rect, x);
            return x;
        }
 /// <summary>
 ///     Calculate cluster's RectangularBoundary to preserve the offsets calculated in initial layout, for example,
 ///     to allow for extra space required for non-shortest path edge routes or for labels.
 /// </summary>
 /// <param name="padding">amount of padding between child node bounding box and expected inner bounds</param>
 internal void SetInitialLayoutState(double padding) {
     isInInitialLayoutState = true;
     if (RectangularBoundary != null) {
         RectangularBoundary.StoreDefaultMargin();
         var childBounds =
             new Rectangle(from v in Nodes.Concat(Clusters) select v.BoundingBox);
         childBounds.Pad(padding);
         RectangularBoundary.LeftMargin = childBounds.Left - RectangularBoundary.Rect.Left;
         RectangularBoundary.RightMargin = RectangularBoundary.Rect.Right - childBounds.Right;
         RectangularBoundary.BottomMargin = childBounds.Bottom - RectangularBoundary.Rect.Bottom;
         RectangularBoundary.TopMargin = RectangularBoundary.Rect.Top - childBounds.Top;
     }
 }
 /// <summary>
 /// </summary>
 /// <param name="padding"></param>
 public void CalculateBoundsFromChildren(double padding) {
     var r = new Rectangle((from v in Nodes select v.BoundingBox).Concat(
         from d in Clusters select d.BoundingBox));
     r.Pad(padding);
     UpdateBoundary(r);
 }