From d3cef1b3c3e9edcf3441d41019ca29b41728a374 Mon Sep 17 00:00:00 2001 From: avalsa Date: Mon, 3 Apr 2017 21:10:15 +0300 Subject: [PATCH 1/2] dsdf --- .../GraphLabs.Graphs.UIComponents.csproj | 3 + .../CirclePositionsVisualizer.cs | 47 ++++++++ .../Visualization/GraphVisualizer.xaml.cs | 100 ++++++------------ .../Visualization/IVisualizationAlgorithm.cs | 19 ++++ .../Visualization/RandomPositionVisualizer.cs | 54 ++++++++++ .../Visualization/VisualizationAlgorithm.cs | 5 + GraphLabs.Tests.UI/MainPage.xaml | 1 + 7 files changed, 159 insertions(+), 70 deletions(-) create mode 100644 GraphLabs.Graphs.UIComponents/Visualization/CirclePositionsVisualizer.cs create mode 100644 GraphLabs.Graphs.UIComponents/Visualization/IVisualizationAlgorithm.cs create mode 100644 GraphLabs.Graphs.UIComponents/Visualization/RandomPositionVisualizer.cs diff --git a/GraphLabs.Graphs.UIComponents/GraphLabs.Graphs.UIComponents.csproj b/GraphLabs.Graphs.UIComponents/GraphLabs.Graphs.UIComponents.csproj index a170ef8..0ab2064 100644 --- a/GraphLabs.Graphs.UIComponents/GraphLabs.Graphs.UIComponents.csproj +++ b/GraphLabs.Graphs.UIComponents/GraphLabs.Graphs.UIComponents.csproj @@ -177,10 +177,13 @@ EditVerticesDialog.xaml + GraphVisualizer.xaml + + diff --git a/GraphLabs.Graphs.UIComponents/Visualization/CirclePositionsVisualizer.cs b/GraphLabs.Graphs.UIComponents/Visualization/CirclePositionsVisualizer.cs new file mode 100644 index 0000000..b418634 --- /dev/null +++ b/GraphLabs.Graphs.UIComponents/Visualization/CirclePositionsVisualizer.cs @@ -0,0 +1,47 @@ +using System; +using System.Linq; + +namespace GraphLabs.Graphs.UIComponents.Visualization +{ + /// + /// по кургу + /// + public class CirclePositionsVisualizer : IVisualizationAlgorithm + { + private GraphVisualizer g_; + + /// + /// constr + /// + public CirclePositionsVisualizer(GraphVisualizer g) + { + g_ = g; + } + + /// + public string Name() + { + return "Circle"; + } + + /// + public void Visualize() + { + var vertices = g_.Vertices; + if (!vertices.Any()) + return; + + var r = Math.Min(g_.ActualHeight, g_.ActualWidth) / 2; + var phi = 0.0; + var deltaPhi = 2 * Math.PI / vertices.Count; + foreach (var vertex in vertices) + { + vertex.ModelX = (r - 2 * g_.DefaultVertexRadius) * Math.Cos(phi) + r; + vertex.ModelY = (r - 2 * g_.DefaultVertexRadius) * Math.Sin(phi) + r; + vertex.ScaleFactor = 1; + + phi += deltaPhi; + } + } + } +} \ No newline at end of file diff --git a/GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs b/GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs index 761e4a8..805ab7d 100644 --- a/GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs +++ b/GraphLabs.Graphs.UIComponents/Visualization/GraphVisualizer.xaml.cs @@ -332,11 +332,37 @@ public VisualizationAlgorithm VisualizationAlgorithm return; } _visualizationAlgorithm = value; + switch (_visualizationAlgorithm) + { + case VisualizationAlgorithm.Circle: + _ivisualizationAlgorithm = new CirclePositionsVisualizer(this); break; + case VisualizationAlgorithm.RandomPositions: + _ivisualizationAlgorithm = new RandomPositionVisualizer(this); break; + default: + throw new Exception("I cant or dont want do it"); + } Refresh(); } } private VisualizationAlgorithm _visualizationAlgorithm; + /// Алгоритм, используемый для визу + public IVisualizationAlgorithm IVisualizationAlgorithm + { + get { return _ivisualizationAlgorithm; } + set + { + if (value == _ivisualizationAlgorithm) + { + return; + } + _visualizationAlgorithm = VisualizationAlgorithm.User; + _ivisualizationAlgorithm = value; + Refresh(); + } + } + private IVisualizationAlgorithm _ivisualizationAlgorithm; + /// Полностью обновляет состояние визуализатора, перечитывая отображаемый граф public void Refresh() { @@ -359,7 +385,7 @@ public void Refresh() { AddEdge(edge); } - CalculateVertexPositions(); + _ivisualizationAlgorithm.Visualize(); _suspendNotifications = false; } @@ -405,52 +431,6 @@ private double GetScaleFactor() return scaleFactor; } - /// Устанавливает начальное рандомное положение вершин - private void SetRandomStartLocations() - { - if (!_vertices.Any()) - return; - - var rnd = new Random(); - - for (var i = 0; i < _vertices.Count; ++i) - { - var vertex = _vertices[i]; - vertex.ModelX = rnd.NextDouble() * (ActualWidth - 2 * DefaultVertexRadius) + DefaultVertexRadius; - vertex.ModelY = rnd.NextDouble() * (ActualHeight - 2 * DefaultVertexRadius) + DefaultVertexRadius; - vertex.ScaleFactor = 1; - - var j = 0; - for (; j < i; j++) - { - if (AreIntersecting(vertex, (Vertex)_vertices[j])) - break; - } - if (j < i) - --i; - } - } - - /// Устанавливает начальные положения вершин по окружности - private void SetCircleLocations() - { - if (!_vertices.Any()) - return; - - var r = Math.Min(ActualHeight, ActualWidth) / 2; - var phi = 0.0; - var deltaPhi = 2*Math.PI/_vertices.Count; - foreach (var vertex in _vertices) - { - vertex.ModelX = (r - 2 * DefaultVertexRadius) * Math.Cos(phi) + r; - vertex.ModelY = (r - 2 * DefaultVertexRadius) * Math.Sin(phi) + r; - vertex.ScaleFactor = 1; - - phi += deltaPhi; - } - - } - /// Рассотяние между v1 и v2 private static double Distance(Vertex v1, Vertex v2) { @@ -458,7 +438,7 @@ private static double Distance(Vertex v1, Vertex v2) } /// Оперделяет, пересекаются ли вершины - private static bool AreIntersecting(Vertex v1, Vertex v2) + public static bool AreIntersecting(Vertex v1, Vertex v2) { return Distance(v1, v2) <= v1.Radius + v2.Radius; } @@ -572,28 +552,7 @@ private void MoveVertices() _animationTimer.Start(); } - /// Считает позиции всех вершин, используя модель с зарядами и пружинками - private void CalculateVertexPositions() - { - switch (_visualizationAlgorithm) - { - case VisualizationAlgorithm.ChargesAndSprings: - SetRandomStartLocations(); - _animationTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(ANIMATION_INTERVAL) }; - _animationTimer.Tick += (s, e) => MoveVertices(); - _animationTimer.Start(); - break; - case VisualizationAlgorithm.RandomPositions: - SetRandomStartLocations(); - break; - case VisualizationAlgorithm.Circle: - SetCircleLocations(); - break; - default: - throw new NotSupportedException( - string.Format("Указан неизвестный алгоритм визуализации {0}", _visualizationAlgorithm)); - } - } + #endregion // Вычисление коориднат вершин @@ -833,6 +792,7 @@ protected virtual void MouseMoveVertex(object sender, MouseEventArgs mouseEventA /// Конструктор public GraphVisualizer() { + _animationTimer = null; InitializeComponent(); _vertices = new ObservableCollection(); _edges = new ObservableCollection(); diff --git a/GraphLabs.Graphs.UIComponents/Visualization/IVisualizationAlgorithm.cs b/GraphLabs.Graphs.UIComponents/Visualization/IVisualizationAlgorithm.cs new file mode 100644 index 0000000..3ce9b75 --- /dev/null +++ b/GraphLabs.Graphs.UIComponents/Visualization/IVisualizationAlgorithm.cs @@ -0,0 +1,19 @@ +namespace GraphLabs.Graphs.UIComponents.Visualization +{ + /// + /// можно сделать свою визуализацию + /// + public interface IVisualizationAlgorithm + { + /// + /// имя алгоритма визуализации + /// + /// + string Name(); + + /// + /// то как мы выпоняем визуализацию + /// + void Visualize(); + } +} \ No newline at end of file diff --git a/GraphLabs.Graphs.UIComponents/Visualization/RandomPositionVisualizer.cs b/GraphLabs.Graphs.UIComponents/Visualization/RandomPositionVisualizer.cs new file mode 100644 index 0000000..87dd414 --- /dev/null +++ b/GraphLabs.Graphs.UIComponents/Visualization/RandomPositionVisualizer.cs @@ -0,0 +1,54 @@ +using System; +using System.Linq; + +namespace GraphLabs.Graphs.UIComponents.Visualization +{ + /// + /// случайные позиции + /// + public class RandomPositionVisualizer : IVisualizationAlgorithm + { + private GraphVisualizer _g; + /// + /// constructor + /// + /// + public RandomPositionVisualizer(GraphVisualizer g) + { + _g = g; + } + + /// + public string Name() + { + return "RandomPositions"; + } + + /// + public void Visualize() + { + var vertices = _g.Vertices; + if (!vertices.Any()) + return; + + var rnd = new Random(); + + for (var i = 0; i < vertices.Count; ++i) + { + var vertex = vertices[i]; + vertex.ModelX = rnd.NextDouble() * (_g.ActualWidth - 2 * _g.DefaultVertexRadius) + _g.DefaultVertexRadius; + vertex.ModelY = rnd.NextDouble() * (_g.ActualHeight - 2 * _g.DefaultVertexRadius) + _g.DefaultVertexRadius; + vertex.ScaleFactor = 1; + + var j = 0; + for (; j < i; j++) + { + if (GraphVisualizer.AreIntersecting(vertex, (Vertex)vertices[j])) + break; + } + if (j < i) + --i; + } + } + } +} \ No newline at end of file diff --git a/GraphLabs.Graphs.UIComponents/Visualization/VisualizationAlgorithm.cs b/GraphLabs.Graphs.UIComponents/Visualization/VisualizationAlgorithm.cs index 72a9935..94d97e7 100644 --- a/GraphLabs.Graphs.UIComponents/Visualization/VisualizationAlgorithm.cs +++ b/GraphLabs.Graphs.UIComponents/Visualization/VisualizationAlgorithm.cs @@ -11,5 +11,10 @@ public enum VisualizationAlgorithm /// Случайные позиции RandomPositions, + + /// + /// типа кастомный алгоритм + /// + User } } diff --git a/GraphLabs.Tests.UI/MainPage.xaml b/GraphLabs.Tests.UI/MainPage.xaml index ddf1fa9..3ecf79e 100644 --- a/GraphLabs.Tests.UI/MainPage.xaml +++ b/GraphLabs.Tests.UI/MainPage.xaml @@ -97,6 +97,7 @@ DefaultEdgeStrokeThickness="2.5" DefaultVertexRadius="15" DefaultVertexBackground="LightGray"/> +