江苏大学 计算机图形学第二次实验报告 曲线拟合
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机科学与通信工程学院
实验报告
课程计算机图形学
实验题目实验二:曲线拟合
学生姓名
学号
专业班级
指导教师
日期
成绩评定表
1. 实验内容
1. 绘制三次Bezier曲线
(1)给定四个已知点P1—P4,以此作为控制顶点绘制一段三次Bezier曲线。(2)给定四个已知点P1—P4,以此作为曲线上的点绘制一段三次Bezier曲线。2. 绘制三次B样条曲线
给定六个已知点P1—P6,以此作为控制顶点绘制一条三次B样条曲线。
2. 实验环境
Windows xp
Vs 2008
3. 问题分析
Bezier曲线通过一组多边折线的各顶点唯一的定义出来。
在多边折线的各顶点中,只有第一点和最后一点在曲线上,其余的顶点则用来定义曲线的导数,阶次和形状。三次Bezieer曲线经过首、末两个控制点,且与特征多边形的首、末两条边相切。
因此在给定四个控制点的情况下,可以根据线性贝塞尔曲线描述的中介点 Q0、Q1、Q2,和由二次曲线描述的点 R0、R1 所建构。也可以在给定四个线上点的情况下根据公式计算出曲线。
总之,只要获得了四个控制点的坐标,便可以通过编程来绘制出曲线。对于给出了四个曲线上点的曲线,由于控制点的坐标位于曲线上,而且在相交处两曲线的切平面重合,曲率相等。可以据此来绘制图形。
B 样条曲线是Bezier 曲线的拓广,它是用B 样条基函数代替了Bezier 曲线表达式中的Bernstain 基函数。在空间给定n +1个点的位置向量P i (i=0,1,2,……n, n>=k),则称参数曲线
,0
()()
n
i i k i Q t t N P ==∑ (0≤t≤1)
为k 阶(或k -1次)的B 样条曲线。其中Ni,k(t)为B 样条基函数。其中Ni,k(t)为B 样条基函数。给定的n +1个点为B 样条曲线的控制顶点,由其构成的多边折线称B 特征多边形。
三次B 样条曲线的端点特性:
图 1 b给定4个点绘制的b样条曲线
三次B样条曲线的连续性:在已有的三次B样条曲线的基础上,增加一个控制点,就可相应地增加一段B样条曲线,并自然地达到 C2连续。
图 2 给定五个点所绘制的b样条曲线
4. 算法设计
下图3为给定四个已知点,以此作为控制顶点绘制一段三次Bezier曲线的流程图。图4为给定四个曲线上点,绘制三次Bezier曲线的流程图。图5为给定六个控制点所绘制三次b样条曲线的流程图。
图3
图 4
图5
5. 源代码
//以已知的四个点为控制点绘制Bezier曲线
void CDiamondView::DrawBezier1(POINT p[4])
{
CDC *pDC = GetDC();
InvalidateRect(NULL);
UpdateWindow();
CPen newPen,*oldPen;
newPen.CreatePen(PS_SOLID,2,RGB(0,0,0));
oldPen = pDC->SelectObject(&newPen);
pDC->Polyline(p,4);
pDC->SelectObject(oldPen);
newPen.DeleteObject();
newPen.CreatePen(PS_SOLID, 1, RGB(255,0,0));
oldPen = pDC->SelectObject(&newPen);
double ax,bx,cx,dx,ay,by,cy,dy,x,y,t;
ax=(-p[0].x)+(3*p[1].x)-(3*p[2].x)+(p[3].x);
bx=(3*p[0].x)-(6*p[1].x)+(3*p[2].x);
cx=(-3*p[0].x)+(3*p[1].x);
dx=p[0].x;
ay=(-p[0].y)+(3*p[1].y)-(3*p[2].y)+(p[3].y);
by=(3*p[0].y)-(6*p[1].y)+(3*p[2].y);
cy=(-3*p[0].y)+(3*p[1].y);
dy=p[0].y;
pDC->MoveTo(p[0].x,p[0].y);
for(t=0;t<=1;t+=0.01)
{
x=ax*t*t*t+bx*t*t+cx*t+dx;
y=ay*t*t*t+by*t*t+cy*t+dy;
pDC->LineTo(x,y);
Sleep(1);
}
pDC->SelectObject(oldPen);
}
//以已知的四个点为Bezier曲线上的点来绘制Bezier曲线void CDiamondView::DrawBezier2(POINT p[4])
{
POINT a[3],b[3];
POINT a1[1],b1[1];
for(int i=0;i<=2;i++)
{
if(i==0)
{
a1[0]=p[i];
b1[0]=p[i+2];
}
else if(i==2)
{
a1[0]=p[i-1];
b1[0]=p[i+1];
}
else
{
a1[0]=p[i-1];
b1[0]=p[i+2];
}
b[i].y=p[i+1].y+((p[i].y)-(b1[0].y))/4;
b[i].x=p[i+1].x+((p[i].x)-(b1[0].x))/4;