AlignSortStrategy
This commit is contained in:
parent
ff6b37420a
commit
d5a67a4571
@ -58,7 +58,7 @@ namespace AsmdefHelper.DependencyGraph.Editor {
|
||||
}
|
||||
|
||||
// ノードの場所を整列
|
||||
var sortStrategy = new RandomSortStrategy(Vector2.zero, 100, 600, 100);
|
||||
var sortStrategy = new AlignSortStrategy(AlignParam.Default(), Vector2.zero);
|
||||
var sortedNode = sortStrategy.Sort(dependencies);
|
||||
foreach (var node in sortedNode) {
|
||||
if (asmdefNodeDict.TryGetValue(node.Profile.Name, out var nodeView)) {
|
||||
|
@ -0,0 +1,50 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AsmdefHelper.DependencyGraph.Editor.DependencyNode.Sort {
|
||||
public struct AlignParam {
|
||||
public readonly int tryCount;
|
||||
|
||||
public readonly float basicDistance;
|
||||
public readonly float nodeWidth;
|
||||
public readonly float nodeHeight;
|
||||
|
||||
public readonly float relationK;
|
||||
public readonly float relationNaturalLength;
|
||||
public readonly float repulsivePower;
|
||||
public readonly float threshold;
|
||||
|
||||
public AlignParam(int tryCount, float basicDistance, float nodeWidth, float nodeHeight,
|
||||
float relationK, float relationNaturalLength, float repulsivePower, float threshold) {
|
||||
this.tryCount = tryCount;
|
||||
this.basicDistance = basicDistance;
|
||||
this.nodeWidth = nodeWidth;
|
||||
this.nodeHeight = nodeHeight;
|
||||
this.relationK = relationK;
|
||||
this.relationNaturalLength = relationNaturalLength;
|
||||
this.repulsivePower = repulsivePower;
|
||||
this.threshold = threshold;
|
||||
}
|
||||
|
||||
public static AlignParam Default() => new AlignParam(1000, 100, 600, 100, -0.01F, 300, 0.01F, 300.0F);
|
||||
}
|
||||
|
||||
public static class AlignParamEx {
|
||||
public static Vector2 接続したノード同士はばねによって引き合う(this AlignParam align, Vector2 target, Vector2 other) {
|
||||
var k = align.relationK;
|
||||
var nl = align.relationNaturalLength;
|
||||
|
||||
var l = (target - other).magnitude;
|
||||
var delta = l - nl;
|
||||
|
||||
return -(delta * k * (other - target).normalized);
|
||||
}
|
||||
public static Vector2 全ノードは互いに斥力が発生する(this AlignParam align, Vector2 target, Vector2 other) {
|
||||
var l = (other - target).magnitude;
|
||||
if (l < align.threshold)
|
||||
{
|
||||
return -(other - target).normalized * ((align.threshold - l) * align.repulsivePower);
|
||||
}
|
||||
return Vector2.zero;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 949ed302d4b143d3b3fea3039ec3f9e9
|
||||
timeCreated: 1605794098
|
@ -0,0 +1,49 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
//https://github.com/TORISOUP/AnimatorControllerLayouter/blob/master/Assets/TORISOUP/AnimatorControllerLayouter/Editor/LayoutHelper.cs
|
||||
namespace AsmdefHelper.DependencyGraph.Editor.DependencyNode.Sort {
|
||||
public class AlignSortStrategy : ISortStrategy {
|
||||
readonly AlignParam alignParam;
|
||||
readonly Vector2 originPosition;
|
||||
|
||||
public AlignSortStrategy(AlignParam alignParam, Vector2 originPosition) {
|
||||
this.alignParam = alignParam;
|
||||
this.originPosition = originPosition;
|
||||
}
|
||||
|
||||
public IEnumerable<SortedNode> Sort(IEnumerable<IDependencyNode> nodes) {
|
||||
var nodeArr = nodes.ToArray();
|
||||
var posDict = nodeArr.ToDictionary(x => x.Profile, _ => originPosition);
|
||||
|
||||
// まず順番に整列させる
|
||||
var nodeGrid = new NodeGrid(alignParam.nodeWidth, alignParam.nodeHeight, alignParam.basicDistance, nodeArr.Length);
|
||||
for (var i = 0; i < nodeArr.Length; i++) {
|
||||
posDict[nodeArr[i].Profile] += nodeGrid.GridCenterPositions()[i];
|
||||
}
|
||||
|
||||
// ばねによる整列
|
||||
var tryCount = alignParam.tryCount;
|
||||
while (tryCount-- > 0) {
|
||||
foreach (var node in nodeArr) {
|
||||
var target = posDict[node.Profile];
|
||||
var force = Vector2.zero;
|
||||
foreach (var innerNode in nodeArr) {
|
||||
var other = posDict[innerNode.Profile];
|
||||
// ばねの計算
|
||||
if (node.IsConnectedTo(innerNode.Profile)) {
|
||||
force += alignParam.接続したノード同士はばねによって引き合う(target, other);
|
||||
}
|
||||
|
||||
force += alignParam.全ノードは互いに斥力が発生する(target, other);
|
||||
}
|
||||
|
||||
posDict[node.Profile] = target + force * 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return posDict.Select(x => new SortedNode { Profile = x.Key, Position = x.Value });
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ebdb87d853042fd96657c9f78cec1a9
|
||||
timeCreated: 1605793928
|
@ -1,4 +1,6 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphs;
|
||||
|
||||
namespace AsmdefHelper.DependencyGraph.Editor.DependencyNode.Sort {
|
||||
public static class DependencyNodeExtensions {
|
||||
@ -18,5 +20,11 @@ namespace AsmdefHelper.DependencyGraph.Editor.DependencyNode.Sort {
|
||||
return node.Sources.Any(x => x == node.Profile) ||
|
||||
node.Destinations.Any(x => x == node.Profile);
|
||||
}
|
||||
public static IEnumerable<NodeProfile> ConnectedNodes(this IDependencyNode node) {
|
||||
return node.Sources.Concat(node.Destinations);
|
||||
}
|
||||
public static bool IsConnectedTo(this IDependencyNode node, NodeProfile nodeProfile) {
|
||||
return node.Sources.Contains(nodeProfile) || node.Destinations.Contains(nodeProfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user