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; }
static internal void ShowHubs(MetroGraphData mgd, BundlingSettings bundlingSettings, bool withIdeal) { if (!withIdeal) return; foreach (var v in mgd.Stations) { ShowHubs(mgd, bundlingSettings, v); } }
public Intersections(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, RectangleNode<Polyline> obstacleTree, Func<Station, Set<Polyline>> obstaclesToIgnore) { this.metroGraphData = metroGraphData; this.obstaclesToIgnore = obstaclesToIgnore; this.bundlingSettings = bundlingSettings; this.obstacleTree = obstacleTree; }
static internal void ShowHubs(MetroGraphData mgd, BundlingSettings bundlingSettings, params ICurve[] iCurves ) { HubDebugger hd = new HubDebugger(mgd, bundlingSettings); if (iCurves != null) { var dc = hd.CreateDebugCurves(iCurves); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(dc); } }
static internal void ShowHubs(MetroGraphData mgd, BundlingSettings bundlingSettings, Station highlightedNode) { HubDebugger hd = new HubDebugger(mgd, bundlingSettings); List<DebugCurve> debugCurves = hd.CreateDebugCurves(); debugCurves.Add(new DebugCurve(100,1, "magenta", CurveFactory.CreateCircle(3, highlightedNode.Position))); debugCurves.Add(new DebugCurve(100, 0.1, "green", highlightedNode.BoundaryCurve)); Console.WriteLine(highlightedNode.SerialNumber); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(debugCurves); }
static internal void ShowHubs(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroMapOrdering, Station station) { var ttt = GetAllDebugCurves(metroMapOrdering, metroGraphData); if (station != null) { ttt = ttt.Concat(new[] { new DebugCurve(255, 3, "pink", CurveFactory.CreateDiamond(20, 20, station.Position)) }); } LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ttt); }
static Point FindCurveEnd(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroOrdering, Metroline metroline) { Station u = metroGraphData.PointToStations[metroline.Polyline.EndPoint.Prev.Point]; Station v = metroGraphData.PointToStations[metroline.Polyline.EndPoint.Point]; BundleBase bb = v.BundleBases[u]; int index = (!bb.IsParent ? metroOrdering.GetLineIndexInOrder(u, v, metroline) : metroOrdering.GetLineIndexInOrder(v, u, metroline)); return(bb.Points[index]); }
static internal void ShowHubs(MetroGraphData mgd, BundlingSettings bundlingSettings, Station highlightedNode) { HubDebugger hd = new HubDebugger(mgd, bundlingSettings); List <DebugCurve> debugCurves = hd.CreateDebugCurves(); debugCurves.Add(new DebugCurve(100, 1, "magenta", CurveFactory.CreateCircle(3, highlightedNode.Position))); debugCurves.Add(new DebugCurve(100, 0.1, "green", highlightedNode.BoundaryCurve)); Console.WriteLine(highlightedNode.SerialNumber); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(debugCurves); }
/// <summary> /// Returns the ideal radius of the hub /// </summary> static double CalculateIdealHubRadiusWithAdjacentEdges(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, Station node) { double r = bundlingSettings.MaxHubRadius; foreach (var adj in node.Neighbors) { r = Math.Min(r, (node.Position - adj.Position).Length / 2); } return(r); }
/// <summary> /// apply a number of heuristics to improve current routing /// </summary> internal static void FixRouting(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { #if DEBUG && TEST_MSAGL Debug.Assert(metroGraphData.looseIntersections.HubPositionsAreOK()); #endif //TimeMeasurer.DebugOutput("Initial cost = " + CostCalculator.Cost(metroGraphData, bundlingSettings)); //TimeMeasurer.DebugOutput("Initial cost of forces: " + CostCalculator.CostOfForces(metroGraphData, bundlingSettings)); var adjuster = new NodePositionsAdjuster(metroGraphData, bundlingSettings); adjuster.GlueConflictingNodes(); adjuster.UnglueEdgesFromBundleToSaveInk(true); var step = 0; int MaxSteps = 10; while (++step < MaxSteps) { /*#if DEBUG && TEST_MSAGL * Debug.Assert(metroGraphData.looseIntersections.HubPositionsAreOK()); #endif*/ //heuristics to improve routing bool progress = adjuster.GlueConflictingNodes(); progress |= adjuster.RelaxConstrainedEdges(); progress |= (step <= 3 && adjuster.UnglueEdgesFromBundleToSaveInk(false)); progress |= adjuster.GlueCollinearNeighbors(step); progress |= (step == 3 && adjuster.RemoveDoublePathCrossings()); if (!progress) { break; } } //one SA has to be executed with bundle forces metroGraphData.cdtIntersections.ComputeForcesForBundles = true; adjuster.RemoveDoublePathCrossings(); adjuster.UnglueEdgesFromBundleToSaveInk(true); while (adjuster.GlueConflictingNodes()) { } metroGraphData.Initialize(true); //this time initialize the tight enterables also // HubDebugger.ShowHubs(metroGraphData, bundlingSettings); //TimeMeasurer.DebugOutput("NodePositionsAdjuster stopped after " + step + " steps"); //HubDebugger.ShowHubs(metroGraphData, bundlingSettings, true); //TimeMeasurer.DebugOutput("Final cost: " + CostCalculator.Cost(metroGraphData, bundlingSettings)); //TimeMeasurer.DebugOutput("Final cost of forces: " + CostCalculator.CostOfForces(metroGraphData, bundlingSettings)); }
static internal void ShowHubs(MetroGraphData mgd, BundlingSettings bundlingSettings, bool withIdeal) { if (!withIdeal) { return; } foreach (var v in mgd.Stations) { ShowHubs(mgd, bundlingSettings, v); } }
/// <summary> /// Returns the ideal radius of the hub /// </summary> static double CalculateIdealHubRadius(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, Station node) { double r = 1.0; foreach (Station adj in node.Neighbors) { double width = metroGraphData.GetWidth(adj, node, bundlingSettings.EdgeSeparation); double nr = width / 2.0 + bundlingSettings.EdgeSeparation; r = Math.Max(r, nr); } r = Math.Min(r, 2 * bundlingSettings.MaxHubRadius); return(r); }
/// <summary> /// Cost of the whole graph /// </summary> static internal double Cost(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { double cost = 0; //ink cost += bundlingSettings.InkImportance * metroGraphData.Ink; //path lengths foreach (var metroline in metroGraphData.Metrolines) { cost += bundlingSettings.PathLengthImportance * metroline.Length / metroline.IdealLength; } cost += CostOfForces(metroGraphData, bundlingSettings); return cost; }
/// <summary> /// apply a number of heuristics to improve current routing /// </summary> internal static void FixRouting(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { #if DEBUG && TEST_MSAGL Debug.Assert(metroGraphData.looseIntersections.HubPositionsAreOK()); #endif //TimeMeasurer.DebugOutput("Initial cost = " + CostCalculator.Cost(metroGraphData, bundlingSettings)); //TimeMeasurer.DebugOutput("Initial cost of forces: " + CostCalculator.CostOfForces(metroGraphData, bundlingSettings)); var adjuster = new NodePositionsAdjuster(metroGraphData, bundlingSettings); adjuster.GlueConflictingNodes(); adjuster.UnglueEdgesFromBundleToSaveInk(true); var step = 0; int MaxSteps = 10; while (++step < MaxSteps) { /*#if DEBUG && TEST_MSAGL Debug.Assert(metroGraphData.looseIntersections.HubPositionsAreOK()); #endif*/ //heuristics to improve routing bool progress = adjuster.GlueConflictingNodes(); progress |= adjuster.RelaxConstrainedEdges(); progress |= (step <= 3 && adjuster.UnglueEdgesFromBundleToSaveInk(false)); progress |= adjuster.GlueCollinearNeighbors(step); progress |= (step == 3 && adjuster.RemoveDoublePathCrossings()); if (!progress) break; } //one SA has to be executed with bundle forces metroGraphData.cdtIntersections.ComputeForcesForBundles = true; adjuster.RemoveDoublePathCrossings(); adjuster.UnglueEdgesFromBundleToSaveInk(true); while (adjuster.GlueConflictingNodes()) { } metroGraphData.Initialize(true); //this time initialize the tight enterables also // HubDebugger.ShowHubs(metroGraphData, bundlingSettings); //TimeMeasurer.DebugOutput("NodePositionsAdjuster stopped after " + step + " steps"); //HubDebugger.ShowHubs(metroGraphData, bundlingSettings, true); //TimeMeasurer.DebugOutput("Final cost: " + CostCalculator.Cost(metroGraphData, bundlingSettings)); //TimeMeasurer.DebugOutput("Final cost of forces: " + CostCalculator.CostOfForces(metroGraphData, bundlingSettings)); }
/// <summary> /// Cost of the whole graph (hubs and bundles) /// </summary> static internal double CostOfForces(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { double cost = 0; //hubs foreach (var v in metroGraphData.VirtualNodes()) { cost += v.cachedRadiusCost; } //bundles foreach (var edge in metroGraphData.VirtualEdges()) { var v = edge.Item1; var u = edge.Item2; cost += metroGraphData.GetIjInfo(v, u).cachedBundleCost; } return cost; }
static ICurve SegOnLineVertex(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroOrdering, Metroline line, PolylinePoint i) { Station u = metroGraphData.PointToStations[i.Prev.Point]; Station v = metroGraphData.PointToStations[i.Point]; BundleBase h0 = v.BundleBases[u]; int j0 = metroOrdering.GetLineIndexInOrder(u, v, line); if (h0.OrientedHubSegments[j0] == null || h0.OrientedHubSegments[j0].Segment == null) { var w = metroGraphData.PointToStations[i.Next.Point]; var otherBase = v.BundleBases[w]; var j1 = metroOrdering.GetLineIndexInOrder(w, v, line); return(new LineSegment(h0.Points[j0], otherBase.Points[j1])); } return(h0.OrientedHubSegments[j0].Segment); }
static IEnumerable <DebugCurve> DebugHubBases(MetroGraphData metroGraphData) { List <DebugCurve> dc = new List <DebugCurve>(); foreach (var s in metroGraphData.Stations) { foreach (var h in s.BundleBases.Values) { dc.Add(new DebugCurve(100, 1, "red", new LineSegment(h.LeftPoint, h.RightPoint))); } } return(dc); //return // metroGraphData.Stations.SelectMany(s => s.BundleBases.Values).Select( // h => new DebugCurve(100, 0.01, "red", new LineSegment(h.Points[0], h.Points.Last()))); }
/// <summary> /// Cost of the whole graph /// </summary> static internal double Cost(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { double cost = 0; //ink cost += bundlingSettings.InkImportance * metroGraphData.Ink; //path lengths foreach (var metroline in metroGraphData.Metrolines) { cost += bundlingSettings.PathLengthImportance * metroline.Length / metroline.IdealLength; } cost += CostOfForces(metroGraphData, bundlingSettings); return(cost); }
/// <summary> /// Returns the ideal radius of the hub /// </summary> internal static double CalculateIdealHubRadiusWithNeighbors(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, Station node, Point newPosition) { double r = CalculateIdealHubRadius(metroGraphData, bundlingSettings, node); if (node.Neighbors.Count() > 1) { Station[] adjNodes = node.Neighbors; //there must be enough space between neighbor bundles for (int i = 0; i < adjNodes.Length; i++) { Station adj = adjNodes[i]; Station nextAdj = adjNodes[(i + 1) % adjNodes.Length]; r = Math.Max(r, GetMinRadiusForTwoAdjacentBundles(r, node, newPosition, adj, nextAdj, metroGraphData, bundlingSettings)); } } r = Math.Min(r, 2 * bundlingSettings.MaxHubRadius); return(r); }
static List <Tuple <Point, Point> > GetInterestingSegs(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroMapOrdering, Metroline line) { var ret = new List <Tuple <Point, Point> >(); Point start = FindCurveStart(metroGraphData, metroMapOrdering, line); var cubicSegs = HubSegsOfLine(metroGraphData, metroMapOrdering, line); foreach (var seg in cubicSegs) { if (seg == null) { continue; } ret.Add(new Tuple <Point, Point>(start, seg.Start)); start = seg.End; } ret.Add(new Tuple <Point, Point>(start, FindCurveEnd(metroGraphData, metroMapOrdering, line))); return(ret); }
/// <summary> /// Cost of the whole graph (hubs and bundles) /// </summary> static internal double CostOfForces(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { double cost = 0; //hubs foreach (var v in metroGraphData.VirtualNodes()) { cost += v.cachedRadiusCost; } //bundles foreach (var edge in metroGraphData.VirtualEdges()) { var v = edge.Item1; var u = edge.Item2; cost += metroGraphData.GetIjInfo(v, u).cachedBundleCost; } return(cost); }
/// <summary> /// Radius we need to draw two adjacent bundles ab and ac /// </summary> internal static double GetMinRadiusForTwoAdjacentBundlesOld(double r, Point a, Point b, Point c, double widthAB, double widthAC, MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { if (widthAB < ApproximateComparer.DistanceEpsilon || widthAC < ApproximateComparer.DistanceEpsilon) { return(r); } double angle = Point.Angle(b, a, c); angle = Math.Min(angle, Math.PI * 2 - angle); if (angle < ApproximateComparer.DistanceEpsilon) { return(2 * bundlingSettings.MaxHubRadius); } //binary search //TODO: solve the equation double L = r; double R = 2 * bundlingSettings.MaxHubRadius; while (Math.Abs(R - L) > 0.1) { double C = (L + R) / 2; double alpha0 = Math.Asin(widthAB / (2 * C)); double alpha1 = Math.Asin(widthAC / (2 * C)); if (alpha0 + alpha1 <= angle) { R = C; } else { L = C; } } return(L); }
/// <summary> /// edge routing with Ordered Bundles: /// 1. route edges with bundling /// 2. nudge bundles and hubs /// 3. order paths /// </summary> protected override void RunInternal() { //TimeMeasurer.DebugOutput("edge bundling started"); if (ThereAreOverlaps(TightHierarchy)) { /* * LayoutAlgorithmSettings.ShowDebugCurves( * TightHierarchy.GetAllLeaves().Select(p => new DebugCurve(100, 1, "black", p)).ToArray());*/ Status = BundlingStatus.Overlaps; TimeMeasurer.DebugOutput("overlaps in edge bundling"); return; } FixLocationsForHookAnywherePorts(geometryGraph.Edges); if (!RoutePathsWithSteinerDijkstra()) { Status = BundlingStatus.EdgeSeparationIsTooLarge; return; } FixChildParentEdges(); if (!bundlingSettings.StopAfterShortestPaths) { var metroGraphData = new MetroGraphData(regularEdges.Select(e => e.EdgeGeometry).ToArray(), LooseHierarchy, TightHierarchy, bundlingSettings, shortestPathRouter.Cdt, EdgeLooseEnterable, EdgeTightEnterable, loosePolylineOfPort); NodePositionsAdjuster.FixRouting(metroGraphData, bundlingSettings); new EdgeNudger(metroGraphData, bundlingSettings).Run(); //TimeMeasurer.DebugOutput("edge bundling ended"); } RouteSelfEdges(); FixArrowheads(); }
/// <summary> /// Constructor /// </summary> internal EdgeNudger(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; }
static Point FindCurveStart(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroOrdering, Metroline metroline) { Station u = metroGraphData.PointToStations[metroline.Polyline.StartPoint.Point]; Station v = metroGraphData.PointToStations[metroline.Polyline.StartPoint.Next.Point]; BundleBase bb = u.BundleBases[v]; int index = (!bb.IsParent ? metroOrdering.GetLineIndexInOrder(v, u, metroline) : metroOrdering.GetLineIndexInOrder(u, v, metroline)); return bb.Points[index]; }
static IEnumerable <DebugCurve> VertexDebugCurves(IMetroMapOrderingAlgorithm metroMapOrdering, MetroGraphData metroGraphData) { return(DebugCircles(metroGraphData).Concat(DebugHubBases(metroGraphData)). Concat(DebugSegs(metroGraphData, metroMapOrdering)). Concat(BetweenHubs(metroMapOrdering, metroGraphData))); }
SimulatedAnnealing(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; costCalculator = new CostCalculator(metroGraphData, bundlingSettings); cache = new IntersectionCache(metroGraphData, bundlingSettings, costCalculator, metroGraphData.Cdt); }
/// <summary> /// fix routing by simulated annealing algorithm /// </summary> internal static bool FixRouting(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { return FixRouting(metroGraphData, bundlingSettings, null); }
internal CostCalculator(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; }
static ICurve SegOnLineVertex(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroOrdering, Metroline line, PolylinePoint i) { Station u = metroGraphData.PointToStations[i.Prev.Point]; Station v = metroGraphData.PointToStations[i.Point]; BundleBase h0 = v.BundleBases[u]; int j0 = metroOrdering.GetLineIndexInOrder(u, v, line); if (h0.OrientedHubSegments[j0] == null || h0.OrientedHubSegments[j0].Segment == null) { var w = metroGraphData.PointToStations[i.Next.Point]; var otherBase = v.BundleBases[w]; var j1 = metroOrdering.GetLineIndexInOrder(w, v, line); return new LineSegment(h0.Points[j0], otherBase.Points[j1]); } return h0.OrientedHubSegments[j0].Segment; }
internal BundleBasesCalculator(IMetroMapOrderingAlgorithm metroOrdering, MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { this.metroOrdering = metroOrdering; this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; }
internal FlipSwitcher(MetroGraphData metroGraphData) { this.metroGraphData = metroGraphData; }
/// <summary> /// edge routing with Ordered Bundles: /// 1. route edges with bundling /// 2. nudge bundles and hubs /// 3. order paths /// </summary> protected override void RunInternal() { //TimeMeasurer.DebugOutput("edge bundling started"); if (ThereAreOverlaps(TightHierarchy)) { /* LayoutAlgorithmSettings.ShowDebugCurves( TightHierarchy.GetAllLeaves().Select(p => new DebugCurve(100, 1, "black", p)).ToArray());*/ Status = BundlingStatus.Overlaps; TimeMeasurer.DebugOutput("overlaps in edge bundling"); return; } FixLocationsForHookAnywherePorts(geometryGraph.Edges); if (!RoutePathsWithSteinerDijkstra()) { Status = BundlingStatus.EdgeSeparationIsTooLarge; return; } FixChildParentEdges(); if (!bundlingSettings.StopAfterShortestPaths) { var metroGraphData = new MetroGraphData(regularEdges.Select(e => e.EdgeGeometry).ToArray(), LooseHierarchy, TightHierarchy, bundlingSettings, shortestPathRouter.Cdt, EdgeLooseEnterable, EdgeTightEnterable, loosePolylineOfPort); NodePositionsAdjuster.FixRouting(metroGraphData, bundlingSettings); new EdgeNudger(metroGraphData, bundlingSettings).Run(); //TimeMeasurer.DebugOutput("edge bundling ended"); } RouteSelfEdges(); FixArrowheads(); }
internal HubDebugger(MetroGraphData mgd, BundlingSettings bundlingSettings) { this.mgd = mgd; this.bundlingSettings = bundlingSettings; }
static internal IEnumerable<DebugCurve> GetAllDebugCurves(IMetroMapOrderingAlgorithm metroMapOrdering, MetroGraphData metroGraphData) { return GraphNodes(metroGraphData).Concat(VertexDebugCurves(metroMapOrdering, metroGraphData)).Concat(DebugEdges(metroGraphData)); }
static IEnumerable<DebugCurve> VertexDebugCurves(IMetroMapOrderingAlgorithm metroMapOrdering, MetroGraphData metroGraphData) { return DebugCircles(metroGraphData).Concat(DebugHubBases(metroGraphData)). Concat(DebugSegs(metroGraphData, metroMapOrdering)). Concat(BetweenHubs(metroMapOrdering, metroGraphData)); }
internal FlipCollapser(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, Cdt cdt) { this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; this.cdt = cdt; }
static List<Tuple<Point, Point>> GetInterestingSegs(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroMapOrdering, Metroline line) { var ret = new List<Tuple<Point, Point>>(); Point start = FindCurveStart(metroGraphData, metroMapOrdering, line); var cubicSegs = HubSegsOfLine(metroGraphData, metroMapOrdering, line); foreach (var seg in cubicSegs) { if (seg == null) continue; ret.Add(new Tuple<Point, Point>(start, seg.Start)); start = seg.End; } ret.Add(new Tuple<Point, Point>(start, FindCurveEnd(metroGraphData, metroMapOrdering, line))); return ret; }
internal static bool FixRouting(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, HashSet<Point> changedPoints) { return new SimulatedAnnealing(metroGraphData, bundlingSettings).FixRouting(changedPoints); }
static IEnumerable<DebugCurve> DebugCircles(MetroGraphData metroGraphData) { return metroGraphData.Stations.Select( station => new DebugCurve(100, 0.1, "blue", CurveFactory.CreateCircle(station.Radius, station.Position))); }
static IEnumerable<ICurve> HubSegsOfLine(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroOrdering, Metroline line) { for (PolylinePoint i = line.Polyline.StartPoint.Next; i.Next != null; i = i.Next) yield return SegOnLineVertex(metroGraphData, metroOrdering, line, i); }
static IEnumerable <DebugCurve> BetweenHubs(IMetroMapOrderingAlgorithm metroMapOrdering, MetroGraphData metroGraphData) { foreach (Metroline ml in metroGraphData.Metrolines) { List <Tuple <Point, Point> > segs = GetInterestingSegs(metroGraphData, metroMapOrdering, ml); string color = GetMonotoneColor(ml.Polyline.Start, ml.Polyline.End, segs); foreach (var seg in segs) { yield return(new DebugCurve(100, ml.Width, color, new LineSegment(seg.Item1, seg.Item2))); } } }
static internal void ShowHubs(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroMapOrdering, Station station) { var ttt = GetAllDebugCurves(metroMapOrdering, metroGraphData); if (station != null) ttt = ttt.Concat(new[] { new DebugCurve(255, 3, "pink", CurveFactory.CreateDiamond(20, 20, station.Position)) }); LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ttt); }
public CdtIntersections(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; }
static IEnumerable<DebugCurve> DebugEdges(MetroGraphData metroGraphData1) { return metroGraphData1.Edges.Select(e => new DebugCurve(40, 0.1, "gray", e.Curve)); }
/// <summary> /// fix routing by simulated annealing algorithm /// </summary> internal static bool FixRouting(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { return(FixRouting(metroGraphData, bundlingSettings, null)); }
static IEnumerable<DebugCurve> BetweenHubs(IMetroMapOrderingAlgorithm metroMapOrdering, MetroGraphData metroGraphData) { foreach (Metroline ml in metroGraphData.Metrolines) { List<Tuple<Point, Point>> segs = GetInterestingSegs(metroGraphData, metroMapOrdering, ml); string color = GetMonotoneColor(ml.Polyline.Start, ml.Polyline.End, segs); foreach (var seg in segs) yield return new DebugCurve(100, ml.Width, color, new LineSegment(seg.Item1, seg.Item2)); } }
internal static bool FixRouting(MetroGraphData metroGraphData, BundlingSettings bundlingSettings, HashSet <Point> changedPoints) { return(new SimulatedAnnealing(metroGraphData, bundlingSettings).FixRouting(changedPoints)); }
static IEnumerable<DebugCurve> DebugHubBases(MetroGraphData metroGraphData) { List<DebugCurve> dc = new List<DebugCurve>(); foreach (var s in metroGraphData.Stations) foreach (var h in s.BundleBases.Values) { dc.Add(new DebugCurve(100, 1, "red", new LineSegment(h.LeftPoint, h.RightPoint))); } return dc; //return // metroGraphData.Stations.SelectMany(s => s.BundleBases.Values).Select( // h => new DebugCurve(100, 0.01, "red", new LineSegment(h.Points[0], h.Points.Last()))); }
NodePositionsAdjuster(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) { this.metroGraphData = metroGraphData; this.bundlingSettings = bundlingSettings; }
static IEnumerable<DebugCurve> DebugSegs(MetroGraphData metroGraphData, IMetroMapOrderingAlgorithm metroMapOrdering) { var ls = new List<ICurve>(); foreach (var s in metroGraphData.VirtualNodes()) { foreach (var b in s.BundleBases.Values) { foreach (var h in b.OrientedHubSegments) { if (h == null) continue; if (h.Segment == null) { var uBase = h.Other.BundleBase; var i = h.Index; var j = h.Other.Index; ls.Add(new LineSegment(b.Points[i], uBase.Points[j])); } else { ls.Add(h.Segment); } } } } return ls.Select(s => new DebugCurve(100, 0.01, "green", s)); }
public PathFixer(MetroGraphData metroGraphData, Func <Metroline, Point, bool> polylineAcceptsPoint) { this.metroGraphData = metroGraphData; this.polylineAcceptsPoint = polylineAcceptsPoint; }
static IEnumerable<DebugCurve> GraphNodes(MetroGraphData metroGraphData) { var nodes = new Set<ICurve>( metroGraphData.Edges.Select(e => e.SourcePort.Curve).Concat( metroGraphData.Edges.Select(e => e.TargetPort.Curve))); return nodes.Select(n => new DebugCurve(40, 1, "black", n)); }
static IEnumerable <DebugCurve> DebugCircles(MetroGraphData metroGraphData) { return (metroGraphData.Stations.Select( station => new DebugCurve(100, 0.1, "blue", CurveFactory.CreateCircle(station.Radius, station.Position)))); }