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);
        }
Пример #2
0
        /// <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);
        }