计算机图形学实验4-----Hermite Bezier B样条三种曲线的绘制

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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 );

相关文档
最新文档