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; }
/// <summary> Возвращает предпочитаемый радиус вершины </summary> public double GetDesiredRadius() { const double DESIRED_DELTA = 5.0; var nameSize = SilverlightHelper.GetTextSize(Name); var desiredRadius = Math.Max(nameSize.Width, nameSize.Height) / 2 + DESIRED_DELTA; return(desiredRadius); }
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(); }