计算机图形学实验4-----Hermite Bezier B样条三种曲线的绘制
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四 Hermite Bezier B样条三种曲线的绘制
一、实验目的
➢了解和学习Hermite、Bezier、B样条三种曲线算法
➢掌握基于 Win32、Visual C++环境MFC绘制图形配置过程制过程
➢编程实现Hermite、Bezier、B样条三种曲线的绘制
二、实验原理
✧三次参数曲线
1.曲线段可以用端点、切向量和曲线段之间的连续性等约束条件来定义
2.两个端点和两端点处的切向量定义Hermite曲线;
3.两个端点和另外两个控制端点切向量的点定义的Bezier曲线;
4.由四个控制顶点定义的样条曲线。
三、实验关键代码
void CDrawYTQXView::Hermite() //绘制Hermite三次插值样条
{
int a[4][4] ={{2,-2,1,1},{-3,3,-2,-1},{0,0,1,0},{1,0,0,0}};//Mh 矩阵系数
int b[4][2];//边界点
for(int i=0;i<4;i++)
{
b[0][0]=p1[i][0];b[0][1]=p1[i][1];//起点的坐标
b[1][0]=p1[i+1][0];b[1][1]=p1[i+1][1];//终点的坐标
b[2][0]=p2[i][0];b[2][1]=p2[i][1];//起点的导数
b[3][0]=p2[i+1][0];b[3][1]=p2[i+1][1];//终点的导数
Caculate(a,b);
CClientDC dc(this);
CPen MyPen,*pOldPen;
MyPen.CreatePen(PS_SOLID,1,RGB(0,0,255));
pOldPen=dc.SelectObject(&MyPen);
dc.MoveTo(p1[i][0],p1[i][1]);
for(double t=0.0;t<=1;t+=1.0/400)
{
int x=ROUND(pow(t,3)*result[0][0]+pow(t,2)*result[1][0]
+ t*result[2][0]+result[3][0]);
int y=ROUND(pow(t,3)*result[0][1]+pow(t,2)*result[1][1]
+ t*result[2][1]+result[3][1]);
dc.LineTo(x,y);
}
dc.SelectObject(pOldPen);
MyPen.DeleteObject();
}
}
void CDrawYTQXView::Caculate(int a[4][4],int b[4][2])//矩阵相乘{
int i,j,k;
for(i=0;i<4;i++)
for(j=0;j<2;j++)
result[i][j]=0; //矩阵清零
for(i=0;i<2;i++)
for(j=0;j<4;j++)
for(k=0;k<4;k++)
result[j][i]+=a[j][k]*b[k][i];
}
void CDrawYTQXView::DrawBezier()//绘制Bezier曲线
{
CClientDC dc(this);
double x,y;
int rate=400,n;
n=CtrlPoint-1;
for(double t=0;t<=1;t+=1.0/rate)
{
x=0;y=0;
for(int i=0;i<=n;i++)
{
x+=pt[i].x*Cnk(n,i)*pow(t,i)*pow(1-t,n-i);
y+=pt[i].y*Cnk(n,i)*pow(t,i)*pow(1-t,n-i);
}
dc.SetPixel(ROUND(x),ROUND(y),RGB(0,0,255)); //曲线颜色}
}
double CDrawYTQXView::Cnk(const int &n, const int &i)//Bernstein 第一项
{
return double(Factorial(n)/(Factorial(i)*Factorial(n-i)));
}
int CDrawYTQXView::Factorial(int m)//阶乘函数
{
int f=1;
for(int i=1;i<=m;i++)
f*=i;
return f;
}
void CDrawYTQXView::DrawB3_curves() //绘制B样条曲线{
CClientDC dc(this);
int i,rate=10,m;
long lx,ly;
m=CtrlPoint-(3+1);
double F03,F13,F23,F33;
lx=ROUND((pt[0].x+4.0*pt[1].x+pt[2].x)/6.0); //t=0的起点x坐标
ly=ROUND((pt[0].y+4.0*pt[1].y+pt[2].y)/6.0);//t=0的起点y坐标
dc.MoveTo(lx,ly);
CPen MyPen2,*pOldPen2;
MyPen2.CreatePen(PS_SOLID,2,RGB(0,0,255)); //颜色设置
pOldPen2=dc.SelectObject(&MyPen2);
for(i=1;i { for(double t=0;t<=1;t+=1.0/rate) { F03=(-t*t*t+3*t*t-3*t+1)/6;//计算F0,3(t) F13=(3*t*t*t-6*t*t+4)/6;//计算F1,3(t) F23=(-3*t*t*t+3*t*t+3*t+1)/6;//计算F2,3(t) F33=t*t*t/6;//计算B3,3(t) lx=ROUND(pt[i-1].x*F03+pt[i].x*F13+pt[i+1].x*F23+pt[i+2].x*F33 );