C# 如何在不使用Windows窗体控件或售后服务包的情况下使用WPF创建样条曲线图?

C# 如何在不使用Windows窗体控件或售后服务包的情况下使用WPF创建样条曲线图?,c#,wpf,mvvm,charts,C#,Wpf,Mvvm,Charts,我需要通过动态数据显示或使用WPF DataVisualization toolkit在WPF中本机创建样条曲线图。有人知道这是否可能吗? 如果是这样,你能给我举一个样条曲线图的例子吗 提前感谢。您是否尝试过此功能?听起来您正在寻找最佳拟合曲线以在WPF中绘制。您必须创建一个自定义控件来绘制它,但是如果可以绘制,贝塞尔样条曲线应该可以很好地为您工作。下面是我编写的一个类,它允许您从一小部分种子点生成一组平滑点。实例化对象,将SeedPoints属性设置为一组点,然后调用GenerateSplin

我需要通过动态数据显示或使用WPF DataVisualization toolkit在WPF中本机创建样条曲线图。有人知道这是否可能吗?
如果是这样,你能给我举一个样条曲线图的例子吗


提前感谢。

您是否尝试过此功能?听起来您正在寻找最佳拟合曲线以在WPF中绘制。您必须创建一个自定义控件来绘制它,但是如果可以绘制,贝塞尔样条曲线应该可以很好地为您工作。下面是我编写的一个类,它允许您从一小部分种子点生成一组平滑点。实例化对象,将SeedPoints属性设置为一组点,然后调用GenerateSpline(int NumberPointsToGenerate)以获取平滑曲线的点。我通常使用大约40个点来生成一条非常平滑的曲线

/// <summary>
/// Class to generate a Bezier Curve from a set of seed points.  
/// Note that this is a best fit curve through a set of points 
/// and a Bezier does NOT require the curve to pass through the points.
/// </summary>
public class BezierSpline
{
    /// <summary>
    /// Default Constructor
    /// </summary>
    public BezierSpline()
    {
        SeedPoints = new List<PointF>();
    }

    /// <summary>
    /// Constructs a BezierSpline object using SeedPoints
    /// </summary>
    /// <param name="seedPoints"></param>
    public BezierSpline(IList<PointF> seedPoints)
        : this()
    {
        SeedPoints = new List<PointF>(seedPoints);
    }

    /// <summary>
    /// Set of SeedPoints to run the spline through
    /// </summary>
    public List<PointF> SeedPoints { get; set; }

    /// <summary>
    /// Generates a smooth curve through a series of points
    /// </summary>
    /// <param name="numberPointsToGenerate">Number of points to generate between P0 and Pn</param>
    /// <returns>IList of Points along the curve</returns>
    public IList<PointF> GenerateSpline(int numberPointsToGenerate)
    {
        List<double> ps = new List<double>();
        List<PointF> np = new List<PointF>();
        for (int i = 0; i < SeedPoints.Count; i++)
        {
            ps.Add(SeedPoints[i].X);
            ps.Add(SeedPoints[i].Y);
        }

        double[] newpts = Bezier2D(ps.ToArray(), numberPointsToGenerate);
        for (int i = 0; i < newpts.Length; i += 2)
            np.Add(new PointF(newpts[i], newpts[i + 1], 0));

        return np;
    }

    private double[] Bezier2D(double[] b, int cpts)
      {
          double[] p = new double[cpts * 2];
          int npts = (b.Length) / 2;
          int icount, jcount;
          double step, t;

          // Calculate points on curve
          icount = 0;
          t = 0;
          step = (double)1 / (cpts - 1);

          for (int i1 = 0; i1 < cpts; i1++)
          { 
              if ((1.0 - t) < 5e-6) 
                  t = 1.0;

              jcount = 0;
              p[icount] = 0.0;
              p[icount + 1] = 0.0;
              for (int i = 0; i != npts; i++)
              {
                  double basis = Bernstein(npts - 1, i, t);
                  p[icount] += basis * b[jcount];
                  p[icount + 1] += basis * b[jcount + 1];
                  jcount += 2;
              }

              icount += 2;
              t += step;
          }
          return p;
      }

    private double Ni(int n, int i)
    {
        return Factorial(n) / (Factorial(i) * Factorial(n - i));
    }

    /// <summary>
    /// Bernstein basis formula
    /// </summary>
    /// <param name="n">n</param>
    /// <param name="i">i</param>
    /// <param name="t">t</param>
    /// <returns>Bernstein basis</returns>
    private double Bernstein(int n, int i, double t)
       {
           double basis;
           double ti; /* t^i */
           double tni; /* (1 - t)^i */

           if (t == 0.0 && i == 0) 
               ti = 1.0; 
           else 
               ti = System.Math.Pow(t, i);

           if (n == i && t == 1.0) 
               tni = 1.0; 
           else 
               tni = System.Math.Pow((1 - t), (n - i));

           //Bernstein basis
           basis = Ni(n, i) * ti * tni; 
           return basis;
       }

    /// <summary>
    /// Gets a single y value for a given x value
    /// </summary>
    /// <param name="x">X value</param>
    /// <returns>Y value at the given location</returns>
    public PointF GetPointAlongSpline(double x)
    {
        return new PointF();
    }

    public static int Factorial(int n)
    {
        int f = 1;

        for (int i = n; i > 1; i--)
            f *= i;
        return f;
    }
}
//
///类从一组种子点生成贝塞尔曲线。
///请注意,这是通过一组点的最佳拟合曲线
///贝塞尔曲线不需要曲线通过这些点。
/// 
公共类贝塞尔样条
{
/// 
///默认构造函数
/// 
公共贝塞尔样条()
{
SeedPoints=新列表();
}
/// 
///使用种子点构造BezierSpline对象
/// 
/// 
公共贝塞尔样条曲线(IList种子点)
:此()
{
种子点=新列表(种子点);
}
/// 
///要穿过样条线的种子点集
/// 
公共列表种子点{get;set;}
/// 
///通过一系列点生成平滑曲线
/// 
///在P0和Pn之间生成的点数
///沿曲线的点的IList
公共IList GenerateSpline(int numberPointsToGenerate)
{
List ps=新列表();
List np=新列表();
for(int i=0;i1;i--)
f*=i;
返回f;
}
}

什么样的样条曲线?最合适?B样条曲线?双三次?我正在寻找的样条曲线图与windows窗体图表控件中提供的样条曲线图相同。奇怪的是,WPF(来自Microsoft)中似乎没有样条曲线可用的表格。是的,奇怪的是,动态数据显示和WPF数据可视化工具包都没有样条曲线…其他每个包似乎都。。。