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); }
/// <summary> /// Gain of path lengths /// </summary> internal double PathLengthsGain(Station node, Point newPosition) { double gain = 0; //edge lengths foreach (var e in metroGraphData.MetroNodeInfosOfNode(node)) { var oldLength = e.Metroline.Length; var prev = e.PolyPoint.Prev.Point; var next = e.PolyPoint.Next.Point; var newLength = e.Metroline.Length + (next - newPosition).Length + (prev - newPosition).Length - (next - node.Position).Length - (prev - node.Position).Length; gain += PathLengthsError(oldLength, newLength, e.Metroline.IdealLength, bundlingSettings); } return(gain); }
/// <summary> /// direction to decrease path lengths /// </summary> Point BuildForceForPathLengths(Station node) { //return new Point(); var direction = new Point(); foreach (var mni in metroGraphData.MetroNodeInfosOfNode(node)) { var metroline = mni.Metroline; Point u = mni.PolyPoint.Next.Point; Point v = mni.PolyPoint.Prev.Point; var p1 = u - node.Position; var p2 = v - node.Position; direction += p1 / (p1.Length * metroline.IdealLength); direction += p2 / (p2.Length * metroline.IdealLength); } //derivative Point force = direction * bundlingSettings.PathLengthImportance; return(force); }