0

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

提前致谢。

4

2 回答 2

0

您是否尝试过PolyBezierSegment

于 2012-05-09T03:55:25.410 回答
0

听起来您正在寻找在 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;
    }
}
于 2012-05-10T17:26:30.260 回答