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
}
}