图表C#在三次贝塞尔曲线中添加数据点

时间:2019-01-14 17:38:27

标签: c# bezier spline microsoft-chart-controls

我已经编写了一种创建Bezier曲线以在Chart控件中进行渲染的方法。我有一组数据点,这些数据点是从另一种方法检索的。我想在图表上形成Bezier曲线,以产生类似于样条曲线的内容,但我收到的是空白图表。产生曲线的代码是:

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
  b = 3,i = 3
  c = 4,f = 5
  d = 3,g = 6

我应该得到这样的曲线:
enter image description here

但是,我在图表上看到的是:
enter image description here

我不确定为什么会这样,请提供任何帮助。

1 个答案:

答案 0 :(得分:0)

似乎您只是在图表中添加一个点;要解决此问题,您需要添加曲线中与您有关的每个点:

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的开始时间开始进行迭代,并使用0.00f - 1.00f将100点添加到图表中。


您已实现的Bezier曲线功能可根据时间为曲线提供特定点。您总是可以编写一个辅助方法,通过为应该返回的点数添加一个参数来为您提供所有点:

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]);

我来看看Wikipedia page关于贝塞尔曲线的构造。我将从二次曲线开始,然后在了解其工作原理之后,继续进行高阶曲线的表示。

  

对于二次贝塞尔曲线,可以构造中间点Q0和Q1,使得t在0到1之间变化。

     
      
  • 点Q0(t)从P0到P1变化,并描述了线性贝塞尔曲线。

  •   
  • 点Q1(t)从P1到P2变化,并描述了线性贝塞尔曲线。

  •   
  • 点B(t)在Q0(t)到Q1(t)之间线性插值,并描述了二次贝塞尔曲线。

  •