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); }