Диаграмма C# добавить точку данных в кубической кривой Безье
Я написал метод для создания кривой Безье для рендеринга в Chart
контроль. У меня есть набор точек данных, которые я получаю из другого метода. Я хотел бы сформировать кривую Безье на моем графике, чтобы получить нечто похожее на сплайн, но вместо этого я получаю пустой график. Код для создания кривой:
public static double XChart(double t, double x0, double x1, double x2, doubl x3)
{
return (double)(
x0 * Math.Pow((1 - t), 3) +
x1 * 3 * t * Math.Pow((1 - t), 2) +
x2 * 3 * Math.Pow(t, 2) * (1 - t) +
x3 * Math.Pow(t, 3)
);
}
Затем я добавляю кривую на график с кодом ниже:
chart1.Series["Series1"].Points.AddXY(XChart(0.1, a, c, b, d), YChart(0.1, l, f, i, g));
куда a, b, c, d, l, f, i, g
значения, которые я получаю из списка точек данных.
List<DataPoint> dataPoints0 = new List<DataPoint>();
var a = dataPoints0[0].XValue;
var b = dataPoints0[1].XValue;
var c = dataPoints0[2].XValue;
var d = dataPoints0[3].XValue;
var l = dataPoints0[0].YValues[0];
var i = dataPoints0[1].YValues[0];
var f = dataPoints0[2].YValues[0];
var g = dataPoints0[3].YValues[0];
Теперь предположим, что:
а = 4, л = 0
б = 3, я = 3
с = 4, f= 5
д = 3, г = 6
Я должен получить кривую, как это:
Тем не менее, то, что я получаю на моем графике это:
Я не уверен, почему это происходит, любая помощь приветствуется.
1 ответ
Похоже, что вы добавляете только одну точку на график; чтобы это исправить, вам нужно добавить каждую точку кривой, которая вас интересует:
for (float t = 0.0f; t < 1.0f; t += 0.01f)
chart1.Series["Series1"].Points.AddXY(XChart(t, a, b, c, d), YChart(t, l, f, i, g));
Приведенный выше пример повторяется с момента начала 0
и добавляет 100 баллов к вашему графику, используя 0.00f - 1.00f
,
Функция кривой Безье, которую вы реализовали, дает вам конкретную точку кривой в зависимости от времени. Вы всегда можете написать вспомогательный метод, который даст вам все баллы, добавив аргумент для количества баллов, которые должны быть возвращены:
public static double XChart(double t, double x0, double x1, double x2, double x3) {
return (double)(
x0 * Math.Pow((1 - t), 3) +
x1 * 3 * t * Math.Pow((1 - t), 2) +
x2 * 3 * Math.Pow(t, 2) * (1 - t) +
x3 * Math.Pow(t, 3));
}
public static double[] XChart(double x0, double x1, double x2, double x3, int totalPoints) {
List<double> points = new List<double>();
for (float t = 0.0f; t < 1.0f; t += (1 / (float)totalPoints))
points.Add(XChart(t, x0, x1, x2, x3));
return points.ToArray();
}
Затем вы можете использовать этот вспомогательный метод для построения диаграммы, как показано ниже:
double[] xPoints = XChart(a, b, c, d, 100);
double[] yPoints = YChart(l, f, i, g, 100);
if (xPoints.Length != yPoints.Length)
throw new InvalidOperationException("The number of points between axes must match.");
for (int i = 0; i < xPoints.Length; i++)
chart1.Series["Series1"].Points.AddXY(xPoints[i], yPoints[i]);
Я бы взглянул на страницу Википедии о построении кривых Безье. Я бы начал с квадратичной кривой, а затем, после понимания того, как она работает, я перешел бы к вашему представлению кривых высокого порядка.
Для квадратичных кривых Безье можно построить промежуточные точки Q0 и Q1 так, чтобы t изменялось от 0 до 1:
Точка Q0(t) изменяется от P0 до P1 и описывает линейную кривую Безье.
Точка Q1(t) изменяется от P1 до P2 и описывает линейную кривую Безье.
Точка B(t) интерполируется линейно между Q0(t) и Q1(t) и описывает квадратичную кривую Безье.