收藏 分销(赏)

计算机图形学实验二报告.doc

上传人:仙人****88 文档编号:8744308 上传时间:2025-02-28 格式:DOC 页数:11 大小:131.50KB 下载积分:10 金币
下载 相关 举报
计算机图形学实验二报告.doc_第1页
第1页 / 共11页
计算机图形学实验二报告.doc_第2页
第2页 / 共11页


点击查看更多>>
资源描述
计算机科学与通信工程学院 实验报告 课程 计算机图形学 实验题目 曲线拟合 学生姓名 学号 专业班级 指导教师 日期 成绩评定表 评价内容 具体内容 权重 得分 论证分析 方案论证与综合分析的正确、合理性 20% 算法设计 算法描述的正确性与可读性 20% 编码实现 源代码正确性与可读性 30% 程序书写规范 标识符定义规范,程序书写风格规范 20% 报告质量 报告清晰,提交准时 10% 总 分 指导教师签名 曲线拟合 1. 实验内容 1. 绘制三次Bezier曲线 (1)给定四个已知点P1—P4,以此作为控制顶点绘制一段三次Bezier曲线。 (2)给定四个已知点P1—P4,以此作为曲线上的点绘制一段三次Bezier曲线。 2. 绘制三次B样条曲线 给定六个已知点P1—P6,以此作为控制顶点绘制一条三次B样条曲线。 2. 实验环境 软硬件运行环境:Windows XP 开发工具:visual studio 2008 3. 问题分析 1. 绘制三次Bezier曲线 Bezier曲线是用N+1个顶点(控制点)所构成的N根折线来 定义一根N阶曲线。本次实验中的三次Bezier曲线有4个顶点,设它们分别为P0,P1,P2,P3,那么对于曲线上各个点Pi(x,y)满足下列关系: P(t)=[(-P0+3P1-3P2+3P3)t3+(3P0-6P1+3P2)t2+(-3P0+3P2)t+(P0+4P1+P2)]/6 X(t)=[(-X0+3X1-3X2+3X3)t3+(3X0-6X1+3X2)t2+(-3X0+3X2)t+(X0+4X1+X2)]/6 Y(t)=[(-Y0+3Y1-3Y2+3Y3)t3+(3Y0-6Y1+3Y2)t2+(-3Y0+3Y2)t+(Y0+4Y1+Y2)]/6 其中P0、P1、P2、P3为四个已知的点,坐标分别为(X0、Y0)、(X1、Y1)、(X1、Y2) 、(X3、Y3)。所以只要确定控制点的坐标,该曲线可通过编程即可绘制出来。 2. 绘制三次B样条曲线 三次B样条函数绘制曲线的光滑连接条件为:对于6个顶点,取P1、P2、P3、 P4 4个顶点绘制在第一段三次样条曲线,再取P2、P3、P4、P5 这4个顶点绘制在第二段三次样条曲线,总计可绘制3段光滑连接的三次样条曲线。 4. 算法设计 程序框架 //DiamondView.h class CDiamondView : public CView { …… public://参数输入和提示对话框 CDlgBezier dlgBezier;//Bezier曲线绘制中的参数输入对话框 CDlgB dlgB;//B样条曲线绘制中的参数输入对话框 //绘图函数,需要实现 void DrawBezier1(POINT p[4]);//已知点作为控制点绘制Bezier曲线 void DrawBezier2(POINT p[4]);//已知点作为曲线上的点绘制Bezier曲线 void DrawBCurve(POINT p[6]);//绘制B样条曲线 //DiamondView.cpp void CDiamondView::OnMenuDiamond() { IsCutting = FALSE; if(dlgDiamond.DoModal()==IDOK) DrawDiamond(dlgDiamond.m_nVertex,dlgDiamond. m_nRadius,100);//调用绘制金刚石的函数 } void CDiamondView::OnMenuBezier1() { IsCutting = FALSE; if(dlgBezier.DoModal() == IDOK) DrawBezier1(dlgBezier.m_nPoint);//调用已知点作为控制点绘制Bezier曲线的函数} //以已知的四个点为控制点绘制Bezier曲线 //p:已知的四个控制点 void CDiamondView::DrawBezier1(POINT p[4]) { } void CDiamondView::OnMenuBezier2() { IsCutting = FALSE; if(dlgBezier.DoModal() == IDOK) DrawBezier2(dlgBezier.m_nPoint);//调用已知点作为曲线上的点绘制Bezier曲线的函数 } //以已知的四个点为Bezier曲线上的点来绘制Bezier曲线 //p:已知的四个点 void CDiamondView::DrawBezier2(POINT p[4]) { } void CDiamondView::OnMenuB() { IsCutting = FALSE; if(dlgB.DoModal() == IDOK) DrawBCurve(dlgB.m_nPoint);//调用绘制B样条曲线的函数} //以已知的六个点为控制点来绘制B样条曲线 //p:已知的六个控制点 void CDiamondView::DrawBCurve(POINT p[6]) { } 5. 源代码 //以已知的四个点为控制点绘制Bezier曲线 //p:已知的四个控制点 void CDiamondView::DrawBezier1(POINT p[4]) { CDC *pDC = GetDC(); CPen newPen,*oldPen; newPen.CreatePen(PS_SOLID,2,RGB(255,0,0)); oldPen = pDC->SelectObject(&newPen); pDC->Polyline(p, 4); pDC->SelectObject(oldPen); newPen.DeleteObject(); newPen.CreatePen(PS_SOLID,2,RGB(0,0,255)); oldPen = pDC->SelectObject(&newPen); int x0=p[0].x; int y0=p[0].y; int x1=p[1].x; int y1=p[1].y; int x2=p[2].x; int y2=p[2].y; int x3=p[3].x; int y3=p[3].y; double x,y; int ax,ay,bx,by,cx,cy,dx,dy; int rate=1000; ax=-x0+3*x1-3*x2+x3; ay=-y0+3*y1-3*y2+y3; bx=3*x0-6*x1+3*x2; by=3*y0-6*y1+3*y2; cx=-3*x0+3*x1; cy=-3*y0+3*y1; dx=x0; dy=y0; pDC->MoveTo(x0,y0); for(double t=0;t<=1;t+=1.0/rate) { x=ax*pow(t,3)+bx*pow(t,2)+cx*t+dx; y=ay*pow(t,3)+by*pow(t,2)+cy*t+dy; pDC->LineTo(Round(x),Round(y)); Sleep(10); } pDC->SelectObject(oldPen); } //以已知的四个点为Bezier曲线上的点来绘制Bezier曲线 //p:已知的四个点 void CDiamondView::DrawBezier2(POINT p[4]) { InvalidateRgn(NULL); UpdateWindow(); CDC *pDC = GetDC(); CPen newPen,*oldPen; newPen.CreatePen(PS_DASH,1,RGB(0,0,0)); oldPen=pDC->SelectObject(&newPen); CBrush newBrush,*oldBrush; newBrush.CreateSolidBrush(RGB(0,0,0)); oldBrush=pDC->SelectObject(&newBrush); for(int i=0;i<=3;i++) {pDC->Ellipse(p[i].x-3,p[i].y-3,p[i].x+3,p[i].y+3);} pDC->SelectObject(oldPen); pDC->SelectObject(oldBrush); Sleep(50); POINT q[4]; q[0].x=p[0].x; q[0].y=p[0].y; q[1].x=(-5*p[0].x+18*p[1].x-9*p[2].x+2*p[3].x)/6; q[1].y=(-5*p[0].y+18*p[1].y-9*p[2].y+2*p[3].y)/6; q[2].x=(2*p[0].x-9*p[1].x+18*p[2].x-5*p[3].x)/6; q[2].y=(2*p[0].y-9*p[1].y+18*p[2].y-5*p[3].y)/6; q[3].x=p[3].x; q[3].y=p[3].y; DrawBezier1(q); } //以已知的六个点为控制点来绘制B样条曲线 //p:已知的六个控制点 void CDiamondView::DrawBCurve(POINT p[6]) { InvalidateRgn(NULL); UpdateWindow(); CDC *pDC = GetDC(); CPen newPen,*oldPen; newPen.CreatePen(PS_SOLID,2,RGB(255,0,0)); oldPen = pDC->SelectObject(&newPen); int rate=1000; int ax,ay,bx,by,cx,cy,dx,dy; double x,y; pDC->Polyline(p, 6); pDC->SelectObject(oldPen); newPen.DeleteObject(); newPen.CreatePen(PS_SOLID,3,RGB(0,0,255)); oldPen = pDC->SelectObject(&newPen); for(int i=0;i<3;i++) { ax=-(p[i].x-3*p[i+1].x+3*p[i+2].x-p[i+3].x)/6; bx=(p[i].x-2*p[i+1].x+p[i+2].x)/2; cx=-(p[i].x-p[i+2].x)/2; dx=(p[i].x+4*p[i+1].x+p[i+2].x)/6; ay=-(p[i].y-3*p[i+1].y+3*p[i+2].y-p[i+3].y)/6; by=(p[i].y-2*p[i+1].y+p[i+2].y)/2; cy=-(p[i].y-p[i+2].y)/2; dy=(p[i].y+4*p[i+1].y+p[i+2].y)/6; for(double t=0;t<=1;t+=1.0/rate) { x=ax*pow(t,3)+bx*pow(t,2)+cx*t+dx; y=ay*pow(t,3)+by*pow(t,2)+cy*t+dy; pDC->MoveTo(Round(x),Round(y)); pDC->LineTo(Round(x),Round(y)); Sleep(2); }} pDC->SelectObject(oldPen);} 6. 程序运行结果 图1 控制顶点一段三次Bezier曲线绘制 图2 控制顶点一段三次Bezier曲线绘制 图3 曲线上的点一段三次Bezier曲线的绘制图4 控制顶点一条三次B样条曲线的绘制 图5 控制顶点一条三次B样条曲线的绘制 7. 总结 通过这次实验,我对Bezier曲线有了一定的了解,同时也懂得了Bezier曲线和B样条曲线的参数表示法。用编程实现了它们的绘制。在此过程中遇到了不少的麻烦,并且逐一解决。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 小学其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服