如题,这里不能贴图,我都不知道如何描述了。
比如说当若干点分布在一条斜率为1的线的两旁或线上时,通过这些点绘制出的曲线就应该是一条斜率为1的直线(不用过线两旁的那些点),而不要绘制出过所有点的象波浪那种上下起伏的曲线。就是说我需要的是一种表示趋势的曲线。
唉,不知表达的如何。哪位知道怎么做嘛?急切等待中……谢谢了

解决方案 »

  1.   

    我在论坛中找了个关于最小二乘法的代码,有些不懂:void CDataBaseDoc::CalculateCurveParameter(CDoubleArray* X, CDoubleArray* Y, CDoubleArray* a, int M, int N)
    M(结果变量组数),N(采样数目)和a(结果参数)是什么意思?
    最近忙着作这个项目,还请多多帮忙,谢谢了
      

  2.   

    你的这个问题,我在高中时用QB做过,效果不错,而且很快,现在没有办法得到源代码了,要不然发给你一份。现在我说一下总体的思路,不过在大学里学了高数以后就知道了一种更高效的公式,现在也忘了。我把高中时的想法告诉你:
    加权公式为:
    x=x1*p+x2*(1-p)       0<=p<=1,p属于实数.
    假设你有n个点
    先申请两个二维数组x[n,n],y[n,n](以后你会知道,其实只要申请一个p[n,n]就可以了,再以后你就会只p[2,n]了,呵呵,当然这只是后话)。x[0,n]填满你的离散点的x坐标,y[0,n]填满对应的y坐标。
    for (p=0,p<=1;p+=0.001)
    {
        for (q=n;q>0;q--)
        {
            for (r=0;r<q;r++)
            {
                 x[n-q+1,r/2]=x[n-q,r]*p+x[n-q,r+1];
                 y[...................]=y.................
            }
         }
        取走曲线上的坐标:(x[n,0],y[n,0])
    }
    (请自己调试)
    早在我的想法之前,德国富特汽车的设计师了明一这个算法来优化汽车的外观模型设计。
    后来微软的Window收录了这种算法,并在Windows3.x时就将其内置于操作系统中,命名为贝塞尔曲线。
    好了,祝你好运!
      

  3.   

    不好意思,好像是这样的:
    for (p=0,p<=1;p+=0.001)
    {
        for (q=n;q>0;q--)
        {
            for (r=0;r<q;r++)
            {
                 x[n-q+1,r]=x[n-q,r]*p+x[n-q,r+1];
                 y[...................]=y.................
            }
         }
        取走曲线上的坐标:(x[n,0],y[n,0])
    }
    就是说把连续的两个点进行两两加权,再把加权后的连续两个数再进行两两加权,直到最后只有一个点,这个点就是你要的曲线上的一个点,连续地把权从0变到1就连续地产生曲线上的点了。
    观注高手更好更快的算法
    祝你好运!
      

  4.   

    说不出具体的代码,但是方法可以试一下:
    用计算方法学中的二乘法(当然还有其他的方法,具体看你的要求了),
    可以用MATLAB编程,直接\便于实现和显示,
    同时提供一个接口,在VC++中调用就便利多了...
      

  5.   

    感谢各位,我找到一个代码,是用最小二乘法作为算法的:不过函数的后三个(共五个嘛)参数不懂是代表什么意思,请高手指点---(代码转至breath)
    typedef CArray<double,double>CDoubleArray;
    BOOL CalculateCurveParameter(CDoubleArray *X,CDoubleArray *Y,long M,long N,CDoubleArray *A)
    {
     //X,Y --  X,Y两轴的坐标
     //M   --  结果变量组数
     //N   --  采样数目
     //A   --  结果参数 register long i,j,k;
     double Z,D1,D2,C,P,G,Q;
     CDoubleArray B,T,S;
     B.SetSize(N);
     T.SetSize(N);
     S.SetSize(N);
     if(M>N)M=N;
     for(i=0;i<M;i++)
      (*A)[i]=0;
     Z=0;
     B[0]=1;
     D1=N;
     P=0;
     C=0;
     for(i=0;i<N;i++)
     {
      P=P+(*X)[i]-Z;
      C=C+(*Y)[i];
     }
     C=C/D1;
     P=P/D1;
     (*A)[0]=C*B[0];
     if(M>1)
     {
      T[1]=1;
      T[0]=-P;
      D2=0;
      C=0;
      G=0;
      for(i=0;i<N;i++)
      {
       Q=(*X)[i]-Z-P;
       D2=D2+Q*Q;
       C=(*Y)[i]*Q+C;
       G=((*X)[i]-Z)*Q*Q+G;
      }
      C=C/D2;
      P=G/D2;
      Q=D2/D1;
      D1=D2;
      (*A)[1]=C*T[1];
      (*A)[0]=C*T[0]+(*A)[0];
     }
     for(j=2;j<M;j++)
     {
      S[j]=T[j-1];
      S[j-1]=-P*T[j-1]+T[j-2];
      if(j>=3)
      {
       for(k=j-2;k>=1;k--)
        S[k]=-P*T[k]+T[k-1]-Q*B[k];
      }
      S[0]=-P*T[0]-Q*B[0];
      D2=0;
      C=0;
      G=0;
      for(i=0;i<N;i++)
      {
       Q=S[j];
       for(k=j-1;k>=0;k--)
        Q=Q*((*X)[i]-Z)+S[k];
       D2=D2+Q*Q;
       C=(*Y)[i]*Q+C;
       G=((*X)[i]-Z)*Q*Q+G;
      }
      C=C/D2;
      P=G/D2;
      Q=D2/D1;
      D1=D2;
      (*A)[j]=C*S[j];
      T[j]=S[j];
      for(k=j-1;k>=0;k--)
      {
       (*A)[k]=C*S[k]+(*A)[k];
       B[k]=T[k];
       T[k]=S[k];
      }
     }
     return TRUE;
    }