用三次拉格朗日插值公式画曲线的算法:
langran(xa,ya,za,k,l_section)
int*xa,*ya,*za,k,l_section;
/*xa,ya,za为存放k个控制点坐标的数组,l_section为每一曲线段的直线段数。*/
{
for(i=0;i {
u=i/l_section;
/*求中间段混合函数值*/
blend[0][i]=u*(u-1)*(u-2)/(-6);
blend[1][i]=(u+1)*(u-1)*(u-2)/2;
blend[2][i]=(u+1)*u*(u-2)/(-2);
blend[3][i]=(u+1)*u*(u-1)/6;
v=u-1;/*求第一段混合函数值*/
f_blend[0][i]=v*(v-1)*(v-2)/(-6);
f_blend[1][i]=(v+1)*(v-1)*(v-2)/2;
f_blend[2][i]=(v+1)*v*(v-2)/(-2);
f_blend[3][i]=(v+1)*v*(v-1)/6;
w=u+1;/*求最后一段混合函数值*/
l_blend[0][i]=w*(w-1)*(w-2)/6;
l_blend[1][i]=(w+1)*(w-1)*(w-2)/2;
l_blend[2][i]=(w+1)*w*(w-2)/(-2);
l_blend[3][i]=(w+1)*w*(w-1)/6;
}
for(i=0;i<4;i++)/*取0~3控制点坐标*/
{
xsm[i]=xa[i];
ysm[i]=ya[i];
zsm[i]=za[i];
}
moveto(xa[0],ya[0];za[0]);
for(j=0,j /*画0—1控制点间的曲线*/
{
x=y=z=0;
for(i=0;i<4;i++)
/*求第j直线段的插值点坐标*/
{
x=x+xsm[i]*f_blend[i][j];
y=y+ysm[i]*f_blend[i][j];
z=z+zsm[i]*f_blend[i][j];
}
lineto(x,y,z);/*画第j个直线段*/
}
for(m=4;m /*依次画出各四个控制点之间的中间曲线段*/
{
for(j=0;j {
x=y=z=0;
for(i=0;i<4;i++)
{
x=x+xsm[i]*blend[i][j];
y=y+ysm[i]*blend[i][j];
z=z+zsm[i]*blend[i][j];
}
lineto(x,y,z);
}
for(i=0;i<3;i++)
/*推进下一个样本点*/
{
xsm[i]=xsm[i+1];
ysm[i]=ysm[i+1];
zsm[i]=zsm[i+1];
}
xsm[3]=xa[m];
ysm[3]=ya[m];
zsm[3]=za[m];
}
for(j=0;j /*画曲线的最后一个曲线段k-1~k点*/
{
x=y=z=0;
for(i=0;i<4;i++)
{
x=x+xsm[i]*l_blend[i][j];
y=y+ysm[i]*l_blend[i][j];
z=z+zsm[i]*l_blend[i][j];
}
lineto(x,y,z);
}
lineto(xsm[3],ysm[3],zsm[3]);
}
langran(xa,ya,za,k,l_section)
int*xa,*ya,*za,k,l_section;
/*xa,ya,za为存放k个控制点坐标的数组,l_section为每一曲线段的直线段数。*/
{
for(i=0;i {
u=i/l_section;
/*求中间段混合函数值*/
blend[0][i]=u*(u-1)*(u-2)/(-6);
blend[1][i]=(u+1)*(u-1)*(u-2)/2;
blend[2][i]=(u+1)*u*(u-2)/(-2);
blend[3][i]=(u+1)*u*(u-1)/6;
v=u-1;/*求第一段混合函数值*/
f_blend[0][i]=v*(v-1)*(v-2)/(-6);
f_blend[1][i]=(v+1)*(v-1)*(v-2)/2;
f_blend[2][i]=(v+1)*v*(v-2)/(-2);
f_blend[3][i]=(v+1)*v*(v-1)/6;
w=u+1;/*求最后一段混合函数值*/
l_blend[0][i]=w*(w-1)*(w-2)/6;
l_blend[1][i]=(w+1)*(w-1)*(w-2)/2;
l_blend[2][i]=(w+1)*w*(w-2)/(-2);
l_blend[3][i]=(w+1)*w*(w-1)/6;
}
for(i=0;i<4;i++)/*取0~3控制点坐标*/
{
xsm[i]=xa[i];
ysm[i]=ya[i];
zsm[i]=za[i];
}
moveto(xa[0],ya[0];za[0]);
for(j=0,j /*画0—1控制点间的曲线*/
{
x=y=z=0;
for(i=0;i<4;i++)
/*求第j直线段的插值点坐标*/
{
x=x+xsm[i]*f_blend[i][j];
y=y+ysm[i]*f_blend[i][j];
z=z+zsm[i]*f_blend[i][j];
}
lineto(x,y,z);/*画第j个直线段*/
}
for(m=4;m /*依次画出各四个控制点之间的中间曲线段*/
{
for(j=0;j {
x=y=z=0;
for(i=0;i<4;i++)
{
x=x+xsm[i]*blend[i][j];
y=y+ysm[i]*blend[i][j];
z=z+zsm[i]*blend[i][j];
}
lineto(x,y,z);
}
for(i=0;i<3;i++)
/*推进下一个样本点*/
{
xsm[i]=xsm[i+1];
ysm[i]=ysm[i+1];
zsm[i]=zsm[i+1];
}
xsm[3]=xa[m];
ysm[3]=ya[m];
zsm[3]=za[m];
}
for(j=0;j /*画曲线的最后一个曲线段k-1~k点*/
{
x=y=z=0;
for(i=0;i<4;i++)
{
x=x+xsm[i]*l_blend[i][j];
y=y+ysm[i]*l_blend[i][j];
z=z+zsm[i]*l_blend[i][j];
}
lineto(x,y,z);
}
lineto(xsm[3],ysm[3],zsm[3]);
}