已知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]);
}
}
uj5u.com熱心網友回復:
gdi+繪制曲線的時候就是三次樣調差值,不用自己算uj5u.com熱心網友回復:
不是的,我這個是下位機發送資料到上位機,要實時顯示的,所以需要插值計算uj5u.com熱心網友回復:
在《Nurbs BOOK》有插值生成三次樣條原始碼,抄過來就可以用。uj5u.com熱心網友回復:
#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;
}
uj5u.com熱心網友回復:
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/12041.html
標籤:圖形處理/算法
