各位高手好,我需要模拟如问题所述绘制这样的曲线(通过拖动控制点绘制平滑曲线),需要寻找一个思路,求助中...谢谢!

解决方案 »

  1.   

    控制点个数大于等于三时用样条函数实现,代码如下:
    double Spline(double* x, double* y, int n, double* t, int m, double* z)
    {
    double* dy = new double[n];
    memset(dy, 0, sizeof(double)*n);
    dy[0] = -0.5; double* ddy = new double[n];
    memset(ddy, 0, sizeof(double)*n); double h1;
    double* s = new double[n];
    double h0 = x[1] - x[0];
    s[0] = 3.0 * (y[1] - y[0]) / (2.0 * h0) - ddy[0] * h0 / 4.0;
    for(int j=1; j<=n-2; j++)
    {
    h1 = x[j+1] - x[j];
    double alpha = h0 / (h0 + h1);
    double beta = (1.0 - alpha) * (y[j] - y[j-1]) / h0;
    beta = 3.0 * (beta + alpha*(y[j+1] - y[j]) / h1);
    dy[j] = -alpha / (2.0 + (1.0 - alpha) * dy[j-1]);
    s[j] = (beta - (1.0 - alpha) * s[j-1]);
    s[j] = s[j] / (2.0 + (1.0 - alpha) * dy[j-1]);
    h0 = h1;
    }
    dy[n-1] = (3.0*(y[n-1] - y[n-2]) / h1 + ddy[n-1] * h1/2.0 - s[n-2]) / (2.0 + dy[n-2]);
    for(int j=n-2; j>=0; j--)
    {
    dy[j] = dy[j] * dy[j+1] + s[j];
    }
    for(int j=0; j<=n-2; j++)
    {
    s[j] = x[j+1] - x[j];
    }
    for(int j=0; j<=n-2; j++)
    {
    h1 = s[j] * s[j];
    ddy[j] = 6.0 * (y[j+1] - y[j]) / h1 - 2.0 * (2.0 * dy[j] + dy[j+1]) / s[j];
    }
    h1 = s[n-2] * s[n-2];
    ddy[n-1] = 6.0 * (y[n-2] - y[n-1]) / h1 + 2.0 * (2.0 * dy[n-1] + dy[n-2]) / s[n-2];
    double g = 0.0;
    for(int i=0; i<=n-2; i++)
    {
    h1 = 0.5 * s[i] * (y[i] + y[i+1]);
    h1 = h1 - s[i] * s[i] * s[i] * (ddy[i] + ddy[i+1]) / 24.0;
    g = g + h1;
    }
    for(int j=0; j<=m-1; j++)
    {
    int i;
    if(t[j] >= x[n-1])
    {
    i = n - 2;
    }
    else
    {
    i = 0;
    while(t[j] > x[i+1])
    {
    i = i + 1;
    }
    }
    h1 = (x[i+1] - t[j]) / s[i];
    h0 = h1 * h1;
    z[j] = (3.0 * h0 - 2.0 * h0 * h1) * y[i];
    z[j] = z[j] + s[i] * (h0 - h0 * h1) * dy[i];
    h1 = (t[j] - x[i]) / s[i];
    h0 = h1 * h1;
    z[j] = z[j] + (3.0 * h0 - 2.0 * h0 * h1) * y[i+1];
    z[j] = z[j] - s[i] * (h0 - h0 * h1) * dy[i+1];
    }
    delete [] s;
    delete [] dy;
    delete [] ddy; return(g);
    }其中输入参数:x、y是控制点的坐标数组,n为控制点个数,m为要插值点的范围
    输出参数:z是样条差值后得到的点的纵坐标值(数组z的大小为m个元素)PS:样条函数计算后,还要对输出的z值进行规范化,防止绘制时超出你的曲线区域。