-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathChartManager.cs
More file actions
120 lines (99 loc) · 4.68 KB
/
ChartManager.cs
File metadata and controls
120 lines (99 loc) · 4.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace Computer_Modeling_Task
{
public class ChartManager
{
private Chart _chart;
private Size _defaultSize;
private int _iterations;
private double _stepValue;
private const int DefaultIterations = 1500;
private const double Default_stepValue = 0.01;
private const double RungeKuttConst = (1.0 / 6);
private const int IterationsStep = 2;
public ChartManager(Chart chart)
{
_chart = chart;
_defaultSize = _chart.Size;
}
public void ClearAll()
{
_chart.Series.Clear();
_chart.Legends.Clear();
_chart.Size = _defaultSize;
_chart.Location = new Point(0, 0);
}
public void Draw(BaseChart chart, string method, double startX, double startY,
double stepValue, int iterations, double[] parameters)
{
_stepValue = stepValue == 0 ? Default_stepValue : stepValue;
_iterations = iterations == 0 ? DefaultIterations : iterations;
string fullName = GetFullName(chart.BaseName, startX, startY, parameters);
if (_chart.Series.FindByName(fullName) == null)
SetupSeries(fullName);
if (method.Equals("Метод Эйлера"))
DrawWithEulerMethod(chart, _chart.Series[fullName], startX, startY, parameters);
else if (method.Equals("Метод Рунге-Кутта"))
DrawWithRungeKutt(chart, _chart.Series[fullName], startX, startY, parameters);
}
private string GetFullName(string baseName, double x, double y, params double[] parameters)
{
var builder = new StringBuilder();
builder.Append(baseName).Append("(X= ").Append(x).Append("; Y= ").Append(y).Append(") ");
if (parameters != null && parameters.Length != 0)
{
builder.Append("{");
for (int i = 0; i < parameters.Length; i++)
builder.Append(parameters[i]).Append("; ");
builder.Append("}");
}
return builder.ToString().Trim();
}
private void SetupSeries(string seriesName)
{
_chart.Series.Add(new Series(seriesName));
_chart.Legends.Add(new Legend(seriesName));
_chart.ChartAreas[0].AxisX.LabelStyle.Format = "{0.00}";
_chart.Series[seriesName].ChartType = SeriesChartType.Spline;
_chart.Legends[seriesName].Font = new Font("TimesNewRoman", 11);
var random = new Random();
_chart.Series[seriesName].Color = Color.FromArgb(random.Next(256), random.Next(128), random.Next(196));
}
private void DrawWithEulerMethod(BaseChart chart, Series series, double x, double y, double[] parameters)
{
for (int i = 0; i < _iterations; i += IterationsStep)
{
series.Points.AddXY(x, y);
/*Если попытаться написать x += _stepValue * chart.f(x, y); y += _stepValue * chart.g(x, y);
* То теряются какие то знаки после запятой, почему?
* */
double nextX = x + _stepValue * chart.f(x, y);
double nextY = y + _stepValue * chart.g(x, y);
x = nextX;
y = nextY;
}
}
private void DrawWithRungeKutt(BaseChart chart, Series series, double x, double y, double[] parameters)
{
for (int i = 0; i < _iterations; i += IterationsStep)
{
double k1 = _stepValue * chart.f(x, y, parameters);
double l1 = _stepValue * chart.g(x, y, parameters);
double k2 = _stepValue * chart.f(x + k1 / 2, y + l1 / 2, parameters);
double l2 = _stepValue * chart.g(x + k1 / 2, y + l1 / 2, parameters);
double k3 = _stepValue * chart.f(x + k2 / 2, y + l2 / 2, parameters);
double l3 = _stepValue * chart.g(x + k2 / 2, y + l2 / 2, parameters);
double k4 = _stepValue * chart.f(x + k3, y + l3, parameters);
double l4 = _stepValue * chart.g(x + k3, y + l3, parameters);
series.Points.AddXY(x, y);
x += RungeKuttConst * Math.Round(k1 + 2 * k2 + 2 * k3 + k4, 5);
y += RungeKuttConst * Math.Round(l1 + 2 * l2 + 2 * l3 + l4, 5);
}
}
}
}