public IntersectionCache(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, CostCalculator costCalculator, Cdt cdt) { Debug.Assert(cdt!=null); this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; this.costCalculator = costCalculator; this.cdt = cdt; }
internal IEnumerable<Point> Calculate(){ if (BoundingBox.Width==0) FillBoundingBoxWithSites(); Cdt cdt = new Cdt(cites, null,null); cdt.Run(); var triangles = cdt.GetTriangles(); foreach (var triangle in triangles) AddVoronoiCite(triangle); return voronoiSiteTree.GetAllLeaves(); }
/// <summary> /// Computes the minimum spanning tree on a DT with given weights. /// </summary> /// <param name="cdt"></param> /// <param name="weights"></param> /// <returns></returns> static internal List<CdtEdge> GetMstOnCdt(Cdt cdt, Func<CdtEdge, double> weights) { var siteArray = cdt.PointsToSites.Values.ToArray(); var siteIndex = new Dictionary<CdtSite, int>(); for (int i = 0; i < siteArray.Length; i++) siteIndex[siteArray[i]] = i; Dictionary<IntPair, CdtEdge> intPairsToCdtEdges = GetEdges(siteArray, siteIndex); var graph = new BasicGraph<IEdge>( intPairsToCdtEdges.Keys, siteArray.Length); var mstOnBasicGraph = new MinimumSpanningTreeByPrim(graph, intPair => weights(intPairsToCdtEdges[(IntPair)intPair]), 0); return new List<CdtEdge>(mstOnBasicGraph.GetTreeEdges().Select(e=>intPairsToCdtEdges[(IntPair)e])); }
internal MetroGraphData(EdgeGeometry[] regularEdges, RectangleNode<Polyline> looseTree, RectangleNode<Polyline> tightTree, BundlingSettings bundlingSettings, Cdt cdt, Dictionary<EdgeGeometry, Set<Polyline>> edgeLooseEnterable, Dictionary<EdgeGeometry, Set<Polyline>> edgeTightEnterable, Func<Port, Polyline> loosePolylineOfPort) { //Debug.Assert(cdt != null); this.regularEdges = regularEdges; if (cdt != null) Cdt = cdt; else Cdt = BundleRouter.CreateConstrainedDelaunayTriangulation(looseTree); EdgeLooseEnterable = edgeLooseEnterable; EdgeTightEnterable = edgeTightEnterable; LoosePolylineOfPort = loosePolylineOfPort; looseIntersections = new Intersections(this, bundlingSettings, looseTree, station => station.EnterableLoosePolylines); tightIntersections = new Intersections(this, bundlingSettings, tightTree, station => station.EnterableTightPolylines); cdtIntersections = new CdtIntersections(this, bundlingSettings); Initialize(false); }
static void TestTriangulationOnSmallGraph(ArgsParser.ArgsParser parser) { var polyline = new Polyline( new Point(20.8211097717285, 40.9088821411133), new Point(21.4894065856934, 46.6845321655273), new Point(22.9755554199219, 41.3355484008789), new Point(20.8211097717285, 40.9088821411133)); var polylines = new List<Polyline>(); polylines.Add(polyline); var points = new List<Point>(); var centroid = new Point(21.7620239257813, 42.9763209025065); points.Add(centroid); var testCdt = new Cdt(points, polylines, null); testCdt.Run(); }
static void Triangulation(bool reverseX) { #if DEBUG DisplayGeometryGraph.SetShowFunctions(); #endif int r = reverseX ? -1 : 1; IEnumerable<Point> points = Points().Select(p => new Point(r*p.X, p.Y)); var poly = (Polyline) RussiaPolyline.GetTestPolyline().ScaleFromOrigin(1, 1); var cdt = new Cdt(null, new[] {poly}, null); cdt.Run(); #if DEBUG CdtSweeper.ShowFront(cdt.GetTriangles(), null, null, null); #endif }
private CdtEdge FindEdge(PolylinePoint a, PolylinePoint b, Cdt cdt) { int aIsAboveB = Cdt.Above(a.Point, b.Point); System.Diagnostics.Debug.Assert(aIsAboveB != 0); if (aIsAboveB > 0) { foreach (var e in cdt.FindSite(a.Point).Edges) if (e.lowerSite.Point == b.Point) return e; } else { foreach (var e in cdt.FindSite(b.Point).Edges) if (e.lowerSite.Point == a.Point) return e; } throw new InvalidOperationException("cannot find an edge of a polyline in the tessellation"); }
static void TestTriangulationOnPolys() { FileStream stream = File.Open("polys", FileMode.Open); var bformatter = new BinaryFormatter(); var polys = (Polyline[]) bformatter.Deserialize(stream); stream.Close(); var cdt = new Cdt(null, polys, null); cdt.Run(); }
private void CleanUpExternalTriangles(Shape shape, ref Set<CdtTriangle> triangles, Cdt cdt) { Set<CdtTriangle> removedTriangles = new Set<CdtTriangle>(); var poly = (Polyline)shape.BoundaryCurve; for (var p = poly.StartPoint; p.Next != null; p = p.Next) FillRemovedForExternalTriangle(p, p.Next, removedTriangles, cdt); FillRemovedForExternalTriangle(poly.EndPoint, poly.StartPoint, removedTriangles, cdt); //var l = new List<DebugCurve>(); //l.Add(new DebugCurve(100, 1, "black", poly)); //l.AddRange(removedTriangles.Select(t => new DebugCurve(100, 0.1, "red", new Polyline(t.Sites.Select(s => s.Point).ToArray()) { Closed = true }))); //LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l); triangles -= removedTriangles; }
private void FillRemovedForExternalTriangle(PolylinePoint a, PolylinePoint b, Set<CdtTriangle> removedTriangles, Cdt cdt) { CdtEdge e = FindEdge(a, b, cdt); if (e.CcwTriangle == null || e.CwTriangle == null) return; bool aligned = a.Point == e.upperSite.Point; if (aligned) { // LayoutAlgorithmSettings.ShowDebugCurves(new DebugCurve(100, 0.1, "black", a.Polyline), new DebugCurve(100, 0.1, "red", new Polyline(e.CcwTriangle.Sites.Select(s => s.Point).ToArray()) { Closed = true })); FillRemovedConnectedRegion(e.CcwTriangle, removedTriangles); } else { // LayoutAlgorithmSettings.ShowDebugCurves(new DebugCurve(100, 0.1, "black", a.Polyline), new DebugCurve(100,0.1,"red", new Polyline(e.CwTriangle.Sites.Select(s => s.Point).ToArray()) { Closed = true })); FillRemovedConnectedRegion(e.CwTriangle, removedTriangles); } }
public void SmallTriangulation() { #if DEBUG&& TEST_MSAGL GraphViewerGdi.DisplayGeometryGraph.SetShowFunctions(); #endif var cdt = new Cdt(Points(), null, new []{new SymmetricTuple<Point>(new Point(109,202),new Point(506,135) ), new SymmetricTuple<Point>(new Point(139,96),new Point(452,96) )}.ToList()); cdt.Run(); }
bool DoSingleIteration(int currentIteration, ref bool scanlinePhase) { List<Tuple<Point, object>> sites = nodePositions.Select((p, index) => new Tuple<Point, object>(p, index)).ToList(); var triangulation = new Cdt(sites); triangulation.Run(); List<Tuple<int, int, double, double>> proximityEdgesWithDistance; int numCrossings = GetProximityEdgesWithDistance(_nodes, triangulation, nodeSizes, out proximityEdgesWithDistance); if (scanlinePhase || numCrossings == 0) { scanlinePhase = true; numCrossings = CompleteProximityGraphWithRTree(ref numCrossings, proximityEdgesWithDistance); } #if DEBUG int realCrossings = CountCrossingsWithRTree(nodeSizes); crossingsOverTime.Add(realCrossings); if (currentIteration%10 == 0) Console.WriteLine("Scanline: {0}, Crossings: {1}", scanlinePhase, numCrossings); #endif if (numCrossings == 0) return true; AddStressFromProximityEdges(StressSolver, proximityEdgesWithDistance); List<Point> newPositions = StressSolver.IterateAll(); ShowCurrentMovementVectors(currentIteration, nodeSizes, nodePositions, newPositions, proximityEdgesWithDistance, null); UpdatePointsAndBoxes(newPositions); //clear the data structures StressSolver.ClearVotings(); #if DEBUG for (int i = 0; i < nodePositions.Length; i++) { trajectories[i].AddPoint(newPositions[i]); } #endif return false; }
void Triangulate(int n, double size) { var random = new Random(n); var w = n * size; var cdt = new Cdt(PointsForCdt(random, n, w), null, SegmentsForCdt(w).ToList()); cdt.Run(); #if DEBUG&&TEST_MSAGL CdtSweeper.ShowFront(cdt.GetTriangles(), null, null,null); #endif }
public void InitCdt() { InitSegmentTree(); for (int i = 0; i < fixedRectangles.Length; i++) { Point p = Round( fixedRectangles[i].Center ); var node = new TreeNode { isFixed = true, rectId = i, rect = fixedRectangles[i], sitePoint = p, type = SiteType.RectFixed }; if (nodeLabelsFixed != null) { node.label = nodeLabelsFixed[i]; } pointToTreeNode[p] = node; _rectNodesRtree.Add(node.rect, node); _fixedRectanglesTree.Add(fixedRectangles[i], node); } for (int i = 0; i < moveableRectangles.Length; i++) { Point p = Round(moveableRectangles[i].Center); var node = new TreeNode { isFixed = false, rectId = i, rect = moveableRectangles[i], sitePoint = p, type = SiteType.RectMoveable }; if (nodeLabelsMoveable != null) { node.label = nodeLabelsMoveable[i]; } pointToTreeNode[p] = node; _rectNodesRtree.Add(node.rect, node); _moveableRectanglesTree.Add(moveableRectangles[i], node); } var sites = pointToTreeNode.Keys.ToList(); //AddSitesForBoxSegmentOverlaps(sites); cdt = new Cdt(sites, null, null); cdt.Run(); }
static Cdt GetConstrainedDelaunayTriangulation(IEnumerable<Polyline> obstacles) { var constrainedDelaunayTriangulation = new Cdt(null, obstacles, null); constrainedDelaunayTriangulation.Run(); return constrainedDelaunayTriangulation; }
internal FlipCollapser(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, Cdt cdt) { this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; this.cdt = cdt; }
internal SdShortestPath(Func<EdgeGeometry, List<Shape>> makeTransparentShapesOfEdgeGeometryAndGetTheShapes, Cdt cdt, Set<CdtEdge> gates) { MakeTransparentShapesOfEdgeGeometry = makeTransparentShapesOfEdgeGeometryAndGetTheShapes; Cdt = cdt; Gates = gates; }
Set<CdtEdge> FindCdtGates(Cdt cdt) { Dictionary<ICurve, Shape> loosePolylinesToLooseParentShapeMap = new Dictionary<ICurve, Shape>(); CreateTheMapToParentLooseShapes(root, loosePolylinesToLooseParentShapeMap); //looking for Cdt edges connecting two siblings; only those we define as gates var gates = new Set<CdtEdge>(); foreach (var cdtSite in cdt.PointsToSites.Values) { foreach (var cdtEdge in cdtSite.Edges) { if(cdtEdge.CwTriangle==null && cdtEdge.CcwTriangle==null) continue; var a = (Polyline)cdtSite.Owner; var b = (Polyline)cdtEdge.lowerSite.Owner; if (a == b) continue; Shape aParent; Shape bParent; if(loosePolylinesToLooseParentShapeMap.TryGetValue(a, out aParent) && loosePolylinesToLooseParentShapeMap.TryGetValue(b, out bParent) && aParent==bParent) gates.Insert(cdtEdge); } } //CdtSweeper.ShowFront(cdt.GetTriangles(), null, // gates.Select(g => new LineSegment(g.upperSite.Point, g.lowerSite.Point)), null); return gates; }
public void TestRepeatedSite() { //in this method the triangulation is such that a repeated site appears in EdgeEvent var stream = File.Open("polys", FileMode.Open); var bformatter = new BinaryFormatter(); var polys = (Polyline[])bformatter.Deserialize(stream); stream.Close(); var cdt = new Cdt(null, polys, null); cdt.Run(); TestTriangles(cdt.GetTriangles()); }
/// <summary> /// /// </summary> public static void Test() { #if DEBUG && !SILVERLIGHT && !SHARPKIT int count = 100; var random = new Random(3); var points = new List<Point>(); for (int i = 0; i < count; i++) points.Add(20 * new Point(random.NextDouble(), random.NextDouble())); var cdt = new Cdt(points, null, null); cdt.Run(); var ret = GetMstOnCdt(cdt, e => (e.lowerSite.Point - e.upperSite.Point).Length); var l = new List<DebugCurve>(); foreach(var s in cdt.PointsToSites.Values) foreach (var e in s.Edges) { l.Add(new DebugCurve(100, 0.1, "black", new LineSegment(e.lowerSite.Point, e.upperSite.Point))); } foreach (var e in ret) { l.Add(new DebugCurve(100, 0.12, "red", new LineSegment(e.lowerSite.Point, e.upperSite.Point))); } LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l); #endif }
private void TesselateUnderShape(Shape shape) { var polys=new List<Polyline>(shape.Children.Select(sh=>(Polyline)sh.BoundaryCurve)); polys.Add(shape.BoundaryCurve as Polyline); var cdt=new Cdt(shapesToInnerPoints[shape], polys,null); cdt.Run(); Set<CdtTriangle> triangles=cdt.GetTriangles(); cdt.SetInEdges(); CleanUpTriangles(shape, ref triangles,cdt); foreach(var t in triangles){ AddTriangleToCanvas(t); } }
static CdtEdge Flip(CdtSite pi, CdtEdge edge) { Debug.Assert(!edge.IsAdjacent(pi)); Debug.Assert(edge.CcwTriangle.Contains(pi) || edge.CwTriangle.Contains(pi)); //get surrounding data CdtTriangle t, ot; if (edge.CcwTriangle.Contains(pi)) { t = edge.CcwTriangle; ot = edge.CwTriangle; } else { t = edge.CwTriangle; ot = edge.CcwTriangle; } Debug.Assert(t.Contains(pi)); var eIndex = t.Edges.Index(edge); var eOtherIndex = ot.Edges.Index(edge); Debug.Assert(eIndex > -1 && eOtherIndex > -1); var pl = ot.Sites[eOtherIndex + 2]; var edgeBeforPi = t.Edges[eIndex + 1]; var edgeBeforPl = ot.Edges[eOtherIndex + 1]; //changing t var newEdge = Cdt.GetOrCreateEdge(pi, pl); t.Sites[eIndex + 1] = pl; t.Edges[eIndex] = edgeBeforPl; t.Edges[eIndex + 1] = newEdge; //changing ot ot.Sites[eOtherIndex + 1] = pi; ot.Edges[eOtherIndex] = edgeBeforPi; ot.Edges[eOtherIndex + 1] = newEdge; //orient the new edge and the two edges that move from one triangle to another if (edgeBeforPl.lowerSite == pl) { edgeBeforPl.CcwTriangle = t; } else { edgeBeforPl.CwTriangle = t; } if (edgeBeforPi.lowerSite == pi) { edgeBeforPi.CcwTriangle = ot; } else { edgeBeforPi.CwTriangle = ot; } if (newEdge.upperSite == pi) { newEdge.CcwTriangle = ot; newEdge.CwTriangle = t; } else { newEdge.CcwTriangle = t; newEdge.CwTriangle = ot; } Debug.Assert(CheckTriangle(t)); Debug.Assert(CheckTriangle(t)); //ShowFlip(pi, t, ot); edge.upperSite.Edges.Remove(edge); //forget the edge return(newEdge); }
private void CleanUpTriangles(Shape shape, ref Set<CdtTriangle> triangles, Cdt cdt) { CleanUpExternalTriangles(shape, ref triangles, cdt); foreach (var sh in shape.Children) CleanUpInternalTriangles(sh, ref triangles, cdt); }
/// <summary> /// Does one iterations in which a miniminum spanning tree is /// determined on the delaunay triangulation and finally the tree is exanded to resolve the overlaps. /// </summary> /// <param name="nodePositions"></param> /// <param name="nodeSizes"></param> /// <param name="scanlinePhase"></param> /// <returns></returns> bool OneIteration(Point[] nodePositions, Size[] nodeSizes, bool scanlinePhase) { var cdt = new Cdt(nodePositions.Select((p, index) => Tuple.Create(p, (object) index))); cdt.Run(); var siteIndex = new Dictionary<CdtSite, int>(); for (int i = 0; i < nodePositions.Length; i++) siteIndex[cdt.PointsToSites[nodePositions[i]]] = i; int numCrossings = 0; List<Tuple<int, int, double, double, double>> proximityEdges = new List<Tuple<int, int, double, double, double>>(); foreach (var site in cdt.PointsToSites.Values) foreach (var edge in site.Edges) { Point point1 = edge.upperSite.Point; Point point2 = edge.lowerSite.Point; var nodeId1 = siteIndex[edge.upperSite]; var nodeId2 = siteIndex[edge.lowerSite]; Debug.Assert(ApproximateComparer.Close(point1, nodePositions[nodeId1])); Debug.Assert(ApproximateComparer.Close(point2, nodePositions[nodeId2])); var tuple = GetIdealEdgeLength(nodeId1, nodeId2, point1, point2, nodeSizes, _overlapForLayers); proximityEdges.Add(tuple); if (tuple.Item3 > 1) numCrossings++; } if (numCrossings == 0 || scanlinePhase) { int additionalCrossings = FindProximityEdgesWithSweepLine(proximityEdges, nodeSizes, nodePositions); if (numCrossings == 0 && additionalCrossings == 0) { // if(nodeSizes.Length>100) // ShowAndMoveBoxesRemoveLater(null, proximityEdges, nodeSizes, nodePositions, -1); return false; } if (numCrossings == 0 && !scanlinePhase) return false; } var treeEdges = MstOnDelaunayTriangulation.GetMstOnTuple(proximityEdges, nodePositions.Length); int rootId = treeEdges.First().Item1; // if (nodeSizes.Length > 100) // ShowAndMoveBoxesRemoveLater(treeEdges, proximityEdges, nodeSizes, nodePositions, rootId); MoveNodePositions(treeEdges, nodePositions, rootId); return true; }
/// <summary> /// Determines the edges of the triangulation together with their desired length (distance between nodes). /// </summary> /// <param name="originalGraph"></param> /// <param name="cdt"></param> /// <param name="targetSizes"></param> /// <param name="desiredEdgeDistances"></param> /// <returns></returns> public static int GetProximityEdgesWithDistance(Node[] originalGraph, Cdt cdt, Size[] targetSizes, out List<Tuple<int, int, double, double>> desiredEdgeDistances) { desiredEdgeDistances = new List<Tuple<int, int, double, double>>(); int numberOverlappingPairs = 0; var edgeSet = new HashSet<CdtEdge>(); //add edges foreach (CdtTriangle triangle in cdt.GetTriangles()) { foreach (CdtEdge triangleEdge in triangle.Edges) { CdtSite site1 = triangleEdge.upperSite; CdtSite site2 = triangleEdge.lowerSite; var nodeId1 = (int) site1.Owner; var nodeId2 = (int) site2.Owner; if (edgeSet.Contains(triangleEdge)) continue; //edge already included edgeSet.Add(triangleEdge); Point point1 = site1.Point; Point point2 = site2.Point; double t; double distance = GetIdealDistanceBetweenNodes(nodeId1, nodeId2, point1, point2, targetSizes, out t); if (t > 1) numberOverlappingPairs++; int nodeIdSmall = nodeId1; int nodeIdBig = nodeId2; if (nodeId1 > nodeId2) { nodeIdSmall = nodeId2; nodeIdBig = nodeId1; } var tuple = new Tuple<int, int, double, double>(nodeIdSmall, nodeIdBig, distance, t); desiredEdgeDistances.Add(tuple); } } return numberOverlappingPairs; }