Files
aistudio-wpf-diagram/AIStudio.Wpf.DiagramDesigner/Layout/Engine.cs
2023-12-21 19:51:50 +08:00

124 lines
4.7 KiB
C#

//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Windows;
//using AIStudio.Wpf.DiagramDesigner.Geometrys;
//namespace AIStudio.Wpf.DiagramDesigner.Layout
//{
// internal class Engine
// {
// internal void ApplyRandomShift(DiagramViewModel network)
// {
// Random random = new Random();
// foreach (var node in network.Items.OfType<DesignerItemViewModelBase>())
// {
// node.Position = node.Position + new VectorBase(random.NextDouble(), random.NextDouble());
// }
// }
// internal void Update(int deltaTMillis, IState state, Configuration config)
// {
// // Calculate forces
// int nodeCount = config.Network.Items.Count;
// IList<(DesignerItemViewModelBase, VectorBase)> nodeForces = new List<(DesignerItemViewModelBase, VectorBase)>(nodeCount);
// foreach (var node in config.Network.Items.OfType<DesignerItemViewModelBase>())
// {
// if (!config.IsFixedNode(node))
// {
// nodeForces.Add((node, CalculateNodeForce(node, state, config)));
// }
// }
// // Apply forces
// foreach (var (node, force) in nodeForces)
// {
// VectorBase speed = state.GetNodeSpeed(node);
// VectorBase pos = state.GetNodePosition(node);
// double deltaT = deltaTMillis / 1000.0;
// state.SetNodePosition(node, pos + ((speed * deltaT) + (force * deltaT * deltaT / 2)));
// state.SetNodeSpeed(node, speed + ((force / config.NodeMass(node)) * deltaT));
// }
// }
// private VectorBase CalculateNodeForce(DesignerItemViewModelBase node, IState state, Configuration config)
// {
// VectorBase force = new VectorBase();
// // Calculate total force on node from endpoints
// if (node.InputConnectors.Count > 0 || node.OutputConnectors.Count > 0)
// {
// force += node.InputConnectors.Concat(node.OutputConnectors)
// .Select(e => CalculateEndpointForce(e, state, config))
// .Aggregate((v1, v2) => v1 + v2);
// }
// // Apply node repulsion force so nodes don't overlap
// var nodeCenter = state.GetNodePosition(node) + (new VectorBase(node.Size.Width, node.Size.Height) / 2.0);
// foreach (var otherNode in config.Network.Items.OfType<DesignerItemViewModelBase>())
// {
// if (node == otherNode)
// {
// continue;
// }
// var otherNodeCenter = state.GetNodePosition(otherNode) + (new VectorBase(otherNode.Size.Width, otherNode.Size.Height) / 2.0);
// var thisToOther = otherNodeCenter - nodeCenter;
// var dist = thisToOther.Length;
// thisToOther.Normalize();
// var repulsionX = thisToOther.X * (-1 * ((node.Size.Width + otherNode.Size.Width) / 2) / dist);
// var repulsionY = thisToOther.Y * (-1 * ((node.Size.Height + otherNode.Size.Height) / 2) / dist);
// force += new VectorBase(repulsionX, repulsionY) * config.NodeRepulsionForce;
// }
// // Apply friction to make the movement converge to a stable state.
// float gravity = 9.8f;
// float normalForce = gravity * config.NodeMass(node);
// float kineticFriction = normalForce * config.FrictionCoefficient(node);
// VectorBase frictionVector = new VectorBase();
// var nodeSpeed = state.GetNodeSpeed(node);
// if (nodeSpeed.Length > 0)
// {
// frictionVector = new VectorBase(nodeSpeed.X, nodeSpeed.Y);
// frictionVector.Normalize();
// frictionVector *= -1.0 * kineticFriction;
// }
// force += frictionVector;
// return force;
// }
// private VectorBase CalculateEndpointForce(ConnectorInfoBase endpoint, IState state, Configuration config)
// {
// var pos = state.GetEndpointPosition(endpoint);
// VectorBase force = new VectorBase();
// foreach (var conn in endpoint.Connections.Items)
// {
// var otherSide = conn.Input == endpoint ? (ConnectorInfoBase)conn.Output : conn.Input;
// var otherSidePos = state.GetEndpointPosition(otherSide);
// var dist = (otherSidePos - pos).Length;
// var angle = Math.Acos((otherSidePos.X - pos.X) / dist);
// if (otherSidePos.Y < pos.Y)
// {
// angle *= -1.0;
// }
// // Put a spring between connected endpoints.
// var hookForce = (dist - config.EquilibriumDistance(conn)) * config.SpringConstant(conn);
// force += new VectorBase(Math.Cos(angle), Math.Sin(angle)) * hookForce;
// // Try to 'straighten' out the graph horizontally.
// var isLeftSide = endpoint.Orientation == ConnectorOrientation.Left;
// var rowForce = (isLeftSide ? 1 : -1) * config.RowForce(conn);
// force.X += rowForce;
// }
// return force;
// }
// }
//}