private void OnVislualizerClick(object sender, MouseButtonEventArgs e)
        {
            if (VisualizerClickCommand != null)
            {
                var position = e.GetPosition(Visualizer);
                var vertex   = new Vertex
                {
                    X = position.X,
                    Y = position.Y,
                    BorderThickness = new Thickness(Visualizer.DefaultVertexBorderThickness),
                    BorderBrush     = Visualizer.DefaultVertexBorderBrush,
                    Background      = Visualizer.DefaultVertexBackground,
                    Style           = Visualizer.DefaultVertexStyle,
                    Radius          = START_NEW_VERTEX_R
                };
                VisualizerClickCommand.Execute(vertex);
                if (vertex.Name != "")
                {
                    Visualizer.AddVertex(vertex);
                }
                vertex.X = position.X;
                vertex.Y = position.Y;

                var animation = SilverlightHelper.GetStoryboard(vertex,
                                                                "Radius",
                                                                20.0,
                                                                0.15,
                                                                null);
                animation.Begin();
            }
            VertVis = Visualizer.Vertices;
        }
Esempio n. 2
0
        private void MoveVertices()
        {
            if (_visualizationAlgorithm != VisualizationAlgorithm.ChargesAndSprings)
            {
                return;
            }

            _animationTimer.Stop();

            if (!IsAnimationSuspended)
            {
                var coordsDeltas = new Point[_vertices.Count];

                // Считаем действующие на вершины силы
                for (var i = 0; i < _vertices.Count; ++i)
                {
                    var vi     = _vertices[i];
                    var fx     = 0.0;
                    var fy     = 0.0;
                    var deltaI = new Point(0.0, 0.0);
                    for (var j = 0; j < _vertices.Count; ++j)
                    {
                        if (j == i)
                        {
                            continue;
                        }
                        var vj = _vertices[j];

                        var distanceIj = Distance(vi, vj);

                        var ex = (vi.ModelX - vj.ModelX) / distanceIj;
                        var ey = (vi.ModelY - vj.ModelY) / distanceIj;
                        fx += G * ex / Math.Pow(distanceIj, 2);
                        fy += G * ey / Math.Pow(distanceIj, 2);

                        if (this[vi, vj] != null || this[vj, vi] != null)
                        {
                            fx -= K * (distanceIj - L) * ex;
                            fy -= K * (distanceIj - L) * ey;
                        }
                        else
                        {
                            fx -= K * (distanceIj - L) * ex / 2;
                            fy -= K * (distanceIj - L) * ey / 2;
                        }

                        deltaI.X += fx * TICK_INTERVAL;
                        deltaI.Y += fy * TICK_INTERVAL;
                    }
                    coordsDeltas[i] = deltaI;
                }

                var newPositions = new Point[_vertices.Count];
                for (var i = 0; i < _vertices.Count; ++i)
                {
                    var vi     = _vertices[i];
                    var deltaI = coordsDeltas[i];
                    newPositions[i].X = vi.ModelX + deltaI.X;
                    newPositions[i].Y = vi.ModelY + deltaI.Y;
                }

                var scaleFactor = GetScaleFactor();

                // Подравниваем, чтобы картинка оставалась в центре
                var minX = newPositions.Min(p => p.X) * scaleFactor;
                var minY = newPositions.Min(p => p.Y) * scaleFactor;
                var maxX = newPositions.Max(p => p.X) * scaleFactor;
                var maxY = newPositions.Max(p => p.Y) * scaleFactor;

                var graphCenter  = new Point((maxX + minX) / 2, (maxY + minY) / 2);
                var layoutCenter = new Point(LayoutRoot.ActualWidth / 2, LayoutRoot.ActualHeight / 2);

                var deltaX = layoutCenter.X - graphCenter.X;
                var deltaY = layoutCenter.Y - graphCenter.Y;

                for (var i = 0; i < newPositions.Length; ++i)
                {
                    newPositions[i].X += deltaX / scaleFactor;
                    newPositions[i].Y += deltaY / scaleFactor;
                }

                // Запускаем анимацию
                for (var i = 0; i < _vertices.Count; ++i)
                {
                    var vi = _vertices[i];
                    if (vi.Equals(CapturedVertex))
                    {
                        continue;
                    }
                    var targetPositionI = newPositions[i];

                    var xiAnimation = SilverlightHelper
                                      .GetStoryboard(vi, "ModelX", targetPositionI.X, ANIMATION_INTERVAL, null);
                    var yiAnimation = SilverlightHelper
                                      .GetStoryboard(vi, "ModelY", targetPositionI.Y, ANIMATION_INTERVAL, null);
                    var scaleAnimation = SilverlightHelper
                                         .GetStoryboard(vi, "ScaleFactor", scaleFactor, ANIMATION_INTERVAL, null);

                    xiAnimation.Begin();
                    yiAnimation.Begin();
                    scaleAnimation.Begin();
                }
            }
            _animationTimer.Start();
        }