三次样条插值问题

qq_28297953 2019-11-22 04:28:58
已知iPeakarrayY[xlabel]和iPeakarrayX[xlabel],是下位机实时发送计算出来的数,现在想进行三次样条插值重绘图形,以下代码是参考网上三次样条插值做的,但是计算不出来,能帮我看看为什么吗?我找不到原因


iPeakarrayY[xlabel] = rawmax;//得到波峰值
iPeakarrayX[xlabel] = ipeakpp;//得到波峰横坐标
RW = rawmax;

/*chafenvalue = iPeakarrayY[xlabel];//返回波峰值*/
//以下为三次样条插值所加
if(xlabel>=2)
{
chafenx[xlabel-1]=iPeakarrayX[xlabel]-iPeakarrayX[xlabel-1];//横坐标
chafenxpp[xlabel-1]=iPeakarrayY[xlabel]-iPeakarrayY[xlabel-1];//纵坐标

//计算x的步长
for(i=1;i<149;i++)
{
h[i]=chafenx[i]-chafenx[i-1];
}
//指定系数,上三角矩阵系数
for(i=1;i<147;i++)
{
A[i]=h[i-1];
B[i] =2 * (h[i] + h[i-1]);//B[i] = 2 * (h[i] + h[i+1]);
C[i] = h[i]; //忽略C(n-1) C[i] = h[i+1];
}
//指定常数D
for (i = 1; i<147; i++)
{
D[i] = 6 * ((chafenxpp[ i ] - chafenxpp[ i-1]) /( h[i -1]+1) - (chafenxpp[i -1] - chafenxpp[ i-2]) / (h[i-2]+1));
}
D[0]=0;
D[300]=0;
//解方程
//上三角矩阵
C[0] = C[0] / 2;
D[0] = D[0] / 2;

for(i = 1; i<149; i++)
{
xcf = (B[i] - A[i] * C[i-1]);
C[i] = C[i] / (xcf+1);
D[i] = (D[i] - A[i] * D[i-1]) /(xcf+1);
}

//直接求出X的最后一个值
X[149] = D[149];

//逆向迭代, 求出X
for(i = 148; i>=0; i--)
{
X[i] = D[i] - C[i] * X[i-1];
}
//自然边界
M[0]=0;
M[149]=0;
for(i=1;i<149;i++)
{
M[i]=X[i-1];
}
//算三次样条曲线的系数
for( i = 0; i < 149; i++)
{
ai[i] = chafenxpp[i];
bi[i] = (chafenxpp[ i ] - chafenxpp[i-1]) / (h[i-1]+1) - (2 * h[i-1] * M[i] + h[i-1] * M[i - 1]) / 6;
ci[i] = M[i] / 2;
di[i] = (M[i ] - M[i-1]) / (6 * h[i]+1);
}
for(i=0;i<150;i++)
{
SRwave[i] = ai[i]+bi[i]*(xlabel-chafenx[i])+ci[i]*(xlabel-chafenx[i])*(xlabel-chafenx[i])+di[i]*(xlabel-chafenx[i])*(xlabel-chafenx[i])*(xlabel-chafenx[i]);

}
}
...全文
249 5 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2020-07-06
  • 打赏
  • 举报
回复

#define POINTS_ON_CURVE 40
// by using LineTo() we do not need too many points.
// if use SetPixel(), increase it !
/** P0、P1、P2、P3 四个点定义了三次方贝塞尔曲线 B(t):
** B(t)=(1-t)*(1-t)*(1-t)*P0+3*t*(1-t)*(1-t)*P1+3*t*t*(1-t)*P2+t*t*t*P3
*************************************************************/
BOOL CTtfShowDlg::CubicBezier(CDC *pDC,const POINT* lpPoints, int nCount)
{// lpPoints contains all points. each 4 points make a cubic Bezier curve.
double t;
double dt=(double)1/POINTS_ON_CURVE;
CPoint pt;
//afxDump << nCount << "=nCount\n";
for(int i=0 ; i < nCount - 3 ; i += 3)
{
if(i==0)
{// only 1 start point need to be set !
pDC->MoveTo(lpPoints[0]);
}
for(t=0.0 ;t < 1.0 + dt ;t += dt)
{// 4 points each,cubic Bezier curve.
pt.x=(long)((1-t)*(1-t)*(1-t)*lpPoints[0+i].x +
3*t*(1-t)*(1-t)*lpPoints[1+i].x +
3*t*t*(1-t)*lpPoints[2+i].x +
t*t*t*lpPoints[3+i].x);
pt.y=(long)((1-t)*(1-t)*(1-t)*lpPoints[0+i].y +
3*t*(1-t)*(1-t)*lpPoints[1+i].y +
3*t*t*(1-t)*lpPoints[2+i].y +
t*t*t*lpPoints[3+i].y);
pDC->LineTo(pt);
//pDC->SetPixel(pt,0xFF0000);// blue !
}
}
return TRUE;
}
schlafenhamster 2020-07-06
  • 打赏
  • 举报
回复
void CTtfShowDlg::DrawCurve(CDC *pDC,BYTE *pBuffer,int BufferLength,GLYPHMETRICS gm,POINT Origin)
{
.......
#ifdef USE_MY_CUBIC
CubicBezier(pDC,Points,PointCount);
#else
pDC->PolyBezier(Points,PointCount);
#endif
Cipherliu 2020-07-05
  • 打赏
  • 举报
回复
在《Nurbs BOOK》有插值生成三次样条源码,抄过来就可以用。
qq_28297953 2019-11-22
  • 打赏
  • 举报
回复
不是的,我这个是下位机发送数据到上位机,要实时显示的,所以需要插值计算
xyll24 2019-11-22
  • 打赏
  • 举报
回复
gdi+绘制曲线的时候就是三次样调差值,不用自己算

19,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧