/// <summary> /// See <see cref="IForce.Apply{TNode,TEdge}"/>. /// </summary> /// <param name="layout">The layout.</param> public void Apply <S, T> (IPhysicalLayout <S, T> layout) where S : Node where T : Edge <S> { foreach (var p in layout.Particles) { foreach (var p2 in layout.Particles) { if (p == p2) { continue; } double dx = p.X - p2.X; double dy = p.Y - p2.Y; double d = Math.Sqrt(dx * dx + dy * dy); double dd = d < 1 ? 1 : d; double ke = .05; double q1 = 1; double q2 = 1; double F = (ke * q1 * q2) / dd * dd; p.XForce += F * dx / dd; p.YForce += F * dy / dd; } } }
/// <summary> /// See <see cref="M:Smog.Force.Apply(PhysicalLayout)"/>. /// </summary> /// <param name="layout"> /// A <see cref="T:PhysicalLayout"/> representing a physical layout. /// </param> public void Apply <TNode, TEdge> (IPhysicalLayout <TNode, TEdge> layout) where TNode : Node where TEdge : Edge <TNode> { foreach (var p in layout.Particles) { foreach (var spring in layout.Springs) { if (!(spring.Particle1 == p || spring.Particle2 == p)) { continue; } var adjacent = spring.Particle1 == p ? spring.Particle2 : spring.Particle1; double dx = p.X - adjacent.X; double dy = p.Y - adjacent.Y; double distance = Math.Sqrt(dx * dx + dy * dy); double dd = distance < 1 ? 1 : distance; if (distance == 0) { var random = new Random(); dx = .01 * (random.NextDouble() - 0.5); dy = .01 * (random.NextDouble() - 0.5); } double k = spring.Strength * (distance - spring.Length); double fx = -k * dx / dd; double fy = -k * dy / dd; p.XForce += fx; p.YForce += fy; } } }