From d5a67a45714f00cff0ae28a1a6996ee3384791e1 Mon Sep 17 00:00:00 2001 From: naninunenoy Date: Thu, 19 Nov 2020 23:41:46 +0900 Subject: [PATCH] AlignSortStrategy --- .../DependencyGraph/Editor/AsmdefGraphView.cs | 2 +- .../Editor/DependencyNode/Sort/AlignParam.cs | 50 +++++++++++++++++++ .../DependencyNode/Sort/AlignParam.cs.meta | 3 ++ .../DependencyNode/Sort/AlignSortStrategy.cs | 49 ++++++++++++++++++ .../Sort/AlignSortStrategy.cs.meta | 3 ++ .../Sort/DependencyNodeExtensions.cs | 10 +++- 6 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignParam.cs create mode 100644 Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignParam.cs.meta create mode 100644 Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignSortStrategy.cs create mode 100644 Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignSortStrategy.cs.meta diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefGraphView.cs b/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefGraphView.cs index df9d8ca..046d1b1 100644 --- a/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefGraphView.cs +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/AsmdefGraphView.cs @@ -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)) { diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignParam.cs b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignParam.cs new file mode 100644 index 0000000..9fe4f5b --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignParam.cs @@ -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; + } + } +} diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignParam.cs.meta b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignParam.cs.meta new file mode 100644 index 0000000..7a1d855 --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignParam.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 949ed302d4b143d3b3fea3039ec3f9e9 +timeCreated: 1605794098 \ No newline at end of file diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignSortStrategy.cs b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignSortStrategy.cs new file mode 100644 index 0000000..e70e37a --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignSortStrategy.cs @@ -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 Sort(IEnumerable 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 }); + } + } +} diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignSortStrategy.cs.meta b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignSortStrategy.cs.meta new file mode 100644 index 0000000..268eba0 --- /dev/null +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/AlignSortStrategy.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5ebdb87d853042fd96657c9f78cec1a9 +timeCreated: 1605793928 \ No newline at end of file diff --git a/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/DependencyNodeExtensions.cs b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/DependencyNodeExtensions.cs index ac694f3..8e6561a 100644 --- a/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/DependencyNodeExtensions.cs +++ b/Assets/AsmdefHelper/DependencyGraph/Editor/DependencyNode/Sort/DependencyNodeExtensions.cs @@ -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 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); + } } }