public MainWindow() { InitializeComponent(); GraphBuilder_SizeChanged(null, null); graphDrawing = new GraphDrawing(DrawingSurface.Width, DrawingSurface.Height); graphDrawing.RadiusChanged += (sender, args1) => { if (BasicTypeCheckBox.Checked) { graphDrawing.DrawTheWholeGraph(digraph); } else { graphDrawing.DrawTheWholeGraphSandpile(digraph, false); } DrawingSurface.Image = graphDrawing.Image; }; VerticesColorPanel.BackColor = graphDrawing.VerticesColor; ArcsColorPanel.BackColor = graphDrawing.ArcsColor; graphDrawing.SandpilePaletteChanged += (sender, e) => DigraphInformationDemonstration.DisplaySandpileColors(graphDrawing, SandpilePalette); CommandsManager.CanRedoChanged += (sender, e) => RedoButton.Enabled = (bool)sender; CommandsManager.CanUndoChanged += (sender, e) => UndoButton.Enabled = (bool)sender; }
/// <summary> /// Initializes new instance of MovementModeling class /// </summary> /// <param name="digraph">Digraph</param> /// <param name="speed">Speed in unit per millisecond</param> /// <param name="type">Modeling type</param> /// <param name="actions">Array of additional actions</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentOutOfRangeException"/> public MovementModeling(Digraph digraph, double speed, MovementModelingType type, MovementModelingActions[] actions) { if (speed <= 0) { throw new ArgumentOutOfRangeException(nameof(speed), @"Speed of movement should be positive"); } this.digraph = digraph ?? throw new ArgumentNullException(nameof(digraph)); this.speed = speed; this.type = type; this.actions = actions; IsActive = false; MovementEnded += (sender, e) => { if (type == MovementModelingType.Sandpile) { GraphDrawing.DrawTheWholeGraphSandpile(digraph, false); } if (type == MovementModelingType.Basic) { GraphDrawing.DrawTheWholeGraph(digraph); } DrawingSurface.Image = GraphDrawing.Image; }; verticesTime = new List <double>(digraph.Vertices.Count); verticesTime.AddRange(digraph.Vertices.ConvertAll(vertex => 0d)); stateReleaseCondition = i => type == MovementModelingType.Sandpile && digraph.State[i] >= incidenceList[i].Count || type == MovementModelingType.Basic && digraph.State[i] >= digraph.Thresholds[i]; refractoryPeriodAdded = new bool[digraph.Vertices.Count]; hasFired = new bool[digraph.Vertices.Count]; lastFires = new Double[digraph.Vertices.Count]; }
/// <summary> /// Draws all the moving dots, removes all the dots got to their destination /// and releases new dots if destination vertices are ready /// </summary> private void ProcessDots() { if (type == MovementModelingType.Basic) { GraphDrawing.DrawTheWholeGraph(digraph); } else { GraphDrawing.DrawTheWholeGraphSandpile(digraph, false); } int newOldMax = -1; for (var i = 0; i < involvedArcs.Count; i++) { if (stopwatches[i].ElapsedMilliseconds >= GetTime(involvedArcs[i].Length, speed)) { if (Math.Max(dotsTime[i], verticesTime[involvedArcs[i].EndVertex]) > oldMax) { oldMax = Math.Max(dotsTime[i], verticesTime[involvedArcs[i].EndVertex]); } bool addTime = !stateReleaseCondition(involvedArcs[i].EndVertex); digraph.State[involvedArcs[i].EndVertex]++; if (verticesTime[involvedArcs[i].EndVertex] < dotsTime[i]) { verticesTime[involvedArcs[i].EndVertex] = dotsTime[i]; } if (!releaseCondition(involvedArcs[i].EndVertex) && stateReleaseCondition(involvedArcs[i].EndVertex) && addTime) { verticesTime[involvedArcs[i].EndVertex] += digraph.RefractoryPeriods[involvedArcs[i].EndVertex] - dotsTime[i] + lastFires[involvedArcs[i].EndVertex]; refractoryPeriodAdded[involvedArcs[i].EndVertex] = true; } stopwatches.RemoveAt(i); involvedArcs.RemoveAt(i); dotsTime.RemoveAt(i); i--; continue; } PointF point = GetPoint(digraph.Vertices[involvedArcs[i].StartVertex], digraph.Vertices[involvedArcs[i].EndVertex], involvedArcs[i].Length, stopwatches[i]); GraphDrawing.DrawDot(point); } if (newOldMax > 0) { oldMax = newOldMax; } CheckDotsNumber(20000); if (type == MovementModelingType.Basic) { GraphDrawing.DrawVertices(digraph); } else { GraphDrawing.DrawVerticesSandpile(digraph); } DrawingSurface.Image = GraphDrawing.Image; }