void AllocateBundleBases() { externalBases = new Dictionary <ICurve, List <BundleBase> >(); internalBases = new Dictionary <ICurve, List <BundleBase> >(); Bundles = new List <BundleInfo>(); foreach (var station in metroGraphData.Stations) { if (station.BoundaryCurve == null) { station.BoundaryCurve = new Ellipse(station.Radius, station.Radius, station.Position); } } foreach (var station in metroGraphData.Stations) { foreach (Station neighbor in station.Neighbors) { if (station < neighbor) { var bb = new BundleBase(metroGraphData.RealEdgeCount(station, neighbor), station.BoundaryCurve, station.Position, station.IsRealNode, neighbor.SerialNumber); station.BundleBases[neighbor] = bb; var bb2 = new BundleBase(metroGraphData.RealEdgeCount(station, neighbor), neighbor.BoundaryCurve, neighbor.Position, neighbor.IsRealNode, station.SerialNumber); neighbor.BundleBases[station] = bb2; if (Curve.PointRelativeToCurveLocation(neighbor.Position, station.BoundaryCurve) != PointLocation.Outside) { bb.IsParent = true; CollectionUtilities.AddToMap(internalBases, station.BoundaryCurve, bb); CollectionUtilities.AddToMap(externalBases, neighbor.BoundaryCurve, bb2); } else if (Curve.PointRelativeToCurveLocation(station.Position, neighbor.BoundaryCurve) != PointLocation.Outside) { bb2.IsParent = true; CollectionUtilities.AddToMap(externalBases, station.BoundaryCurve, bb); CollectionUtilities.AddToMap(internalBases, neighbor.BoundaryCurve, bb2); } else { CollectionUtilities.AddToMap(externalBases, station.BoundaryCurve, bb); CollectionUtilities.AddToMap(externalBases, neighbor.BoundaryCurve, bb2); } Set <Polyline> obstaclesToIgnore = metroGraphData.tightIntersections.ObstaclesToIgnoreForBundle(station, neighbor); var bundle = new BundleInfo(bb, bb2, obstaclesToIgnore, bundlingSettings.EdgeSeparation, metroOrdering.GetOrder(station, neighbor).Select(l => l.Width / 2).ToArray()); bb.OutgoingBundleInfo = bb2.IncomingBundleInfo = bundle; Bundles.Add(bundle); } } } //neighbors SetBundleBaseNeighbors(); }
double ComputeCostDeltaAfterNodeGluing(Station i, Station j, Dictionary <Station, Station> gluingMap) { double d = (i.Position - j.Position).Length; if (i.Radius >= d || j.Radius >= d) { return(1.0); } double gain = 0; //ink double oldInk = metroGraphData.Ink; double newInk = metroGraphData.Ink - (j.Position - i.Position).Length; foreach (var adj in i.Neighbors) { var k = Glued(adj, gluingMap); newInk -= (k.Position - i.Position).Length; newInk += (metroGraphData.RealEdgeCount(k, j) == 0 ? (k.Position - j.Position).Length : 0); } gain += CostCalculator.InkError(oldInk, newInk, bundlingSettings); //path lengths foreach (var metroInfo in metroGraphData.MetroNodeInfosOfNode(i)) { double oldLength = metroInfo.Metroline.Length; double newLength = metroInfo.Metroline.Length; PolylinePoint pi = metroInfo.PolyPoint; PolylinePoint pa = pi.Prev; PolylinePoint pb = pi.Next; newLength -= (pa.Point - i.Position).Length + (pb.Point - i.Position).Length; newLength += (pa.Point - j.Position).Length + (pb.Point - j.Position).Length; gain += CostCalculator.PathLengthsError(oldLength, newLength, metroInfo.Metroline.IdealLength, bundlingSettings); } return(gain); }