Диаграмма C # добавить точку данных в кубической кривой Безье - PullRequest
0 голосов
/ 14 января 2019

Я написал метод для создания кривой Безье для рендеринга в элементе управления 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];

Теперь предположим, что:

a = 4, l = 0
б = 3, я = 3
с = 4, f = 5
д = 3, г = 6

Я должен получить кривую так:
enter image description here

Однако на графике я получаю следующее:
enter image description here

Я не уверен, почему это происходит, любая помощь приветствуется.

1 Ответ

0 голосов
/ 14 января 2019

Похоже, что вы добавляете только одну точку на график; чтобы исправить это, вам нужно добавить каждую точку кривой, которая вас интересует:

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) и описывает квадратичную кривую Безье.

...