using System; using System.Collections.Generic; using Microsoft.Msagl.Core.Geometry; using Microsoft.Msagl.Core.Layout; namespace Microsoft.Msagl.Layout.Incremental { /// /// A stick constraint requires a fixed separation between two nodes /// public class StickConstraint : IConstraint { /// /// /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] protected Node u; /// /// /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] protected Node v; /// /// /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] protected double separation; /// /// /// /// /// /// public StickConstraint(Node u, Node v, double separation) { this.u = u; this.v = v; this.separation = separation; } /// /// /// public virtual double Project() { Point uv = v.Center - u.Center; double d = separation - uv.Length, wu = ((FiNode)u.AlgorithmData).stayWeight, wv = ((FiNode)v.AlgorithmData).stayWeight; Point f = d * uv.Normalize() / (wu + wv); u.Center -= wv * f; v.Center += wu * f; return Math.Abs(d); } /// /// StickConstraints are usually structural and therefore default to level 0 /// /// 0 public int Level { get { return 0; } } /// /// Get the list of nodes involved in the constraint /// public IEnumerable Nodes { get { return new Node[]{ u, v }; } } } }