using System; namespace Netron.Diagramming.Core.Layout.Force { /// /// Force function that computes the force acting on ForceItems due to a given Spring. /// public class SpringForce : AbstractForce { #region Fields Random rnd = new Random(); private static String[] pnames = new String[] { "SpringCoefficient", "DefaultSpringLength" }; public static float DefaultSpriongCoeff = 1E-4f; public static float DefaultMaxSpringCoeff = 1E-3f; public static float DefaultMinSpringCoeff = 1E-5f; public static float DefaultSpringLength = 50; public static float DefaultMinSpringLength = 0; public static float DefaultMaxSpringLength = 200; public static int SpringCoeff = 0; public static int SpringLength = 1; #endregion #region Properties /// /// Gets a value indicating whether [spring force]. /// /// true if [spring force]; otherwise, false. public override bool IsSpringForce { get { return true; } } /// /// Gets the parameter names. /// /// /// protected override String[] ParameterNames { get { return pnames; } } #endregion #region Constructor /// /// Create a new SpringForce. /// /// the default spring co-efficient to use. This will be used if the spring's own co-efficient is less than zero.. /// the default spring length to use. This will be used if the spring's own length is less than zero. public SpringForce(float springCoeff, float defaultLength) { parms = new float[] { springCoeff, defaultLength }; minValues = new float[] { DefaultMinSpringCoeff, DefaultMinSpringLength }; maxValues = new float[] { DefaultMaxSpringCoeff, DefaultMaxSpringLength }; } /// /// Constructs a new SpringForce instance with default parameters. /// public SpringForce() : this(DefaultSpriongCoeff, DefaultSpringLength) { } #endregion #region Methdos /// /// Gets the force. /// /// The s. public override void GetForce(Spring s) { ForceItem item1 = s.Item1; ForceItem item2 = s.Item2; float length = (s.Length < 0 ? parms[SpringLength] : s.Length); float x1 = item1.Location[0], y1 = item1.Location[1]; float x2 = item2.Location[0], y2 = item2.Location[1]; float dx = x2 - x1, dy = y2 - y1; float r = (float)Math.Sqrt(dx * dx + dy * dy); if (r == 0.0) { dx = ((float)rnd.NextDouble() - 0.5f) / 50.0f; dy = ((float)rnd.NextDouble() - 0.5f) / 50.0f; r = (float)Math.Sqrt(dx * dx + dy * dy); } float d = r - length; float coeff = (s.Coeff < 0 ? parms[SpringCoeff] : s.Coeff) * d / r; item1.Force[0] += coeff * dx; item1.Force[1] += coeff * dy; item2.Force[0] += -coeff * dx; item2.Force[1] += -coeff * dy; } #endregion } }