Bezier曲线的绘制和拼接实验报告
- 格式:docx
- 大小:155.17 KB
- 文档页数:11
实验四实现Bezier曲线的生成算法一、实验目的1、熟悉CDC图形程序库;2、掌握Bezier曲线的生成算法;3、掌握利用Bezier曲线生成复杂形状的曲线;二、实验性质验证性三、实验要求1、认真阅读本次实验的目的,了解本次实验要求掌握的内容;2、能够根据实验指导书的要求,完成相关的内容;四、实验内容(一)生成绘图应用程序的框架(如下图)具体实现见第一次实验,过程不再详细说明。
(二)在应用程序中增加菜单完成相关菜单的设计,具体的效果如下图所示,并设置好相关菜单消息的映射,具体的实现在前面的实验中介绍过,再此不在详细说明。
(三)在绘图函数中添加代码通过以上步骤,得到了与菜单对应的消息映射,就可以在函数中添加代码绘制图形了。
1、利用Bezier曲线的生成算法实现二次Bezier曲线的生成(算法的详细原理见教材)。
void CBezierV iew::OnBezier2(){// TODO: Add your command handler code hereCDC*pDC=GetDC();//得到绘图类指针RedrawWindow();//重绘窗口CPen bluepen(PS_SOLID,2,RGB(0,0,255));//创建画实线、线宽为2的蓝色画笔CPen *old=pDC->SelectObject(&bluepen);float x0=100,y0=100,x1=200,y1=50,x2=150,y2=250;float i,x,y,dt,t,n=30.0;dt=1/n;for(i=0;i<=n;i++){t=i*dt;x=x0*(1-t)*(1-t)+x1*2*t*(1-t)+x2*t*t;y=y0*(1-t)*(1-t)+y1*2*t*(1-t)+y2*t*t;if(i==0)pDC->MoveTo(x,y);pDC->LineTo(x,y);pDC->MoveTo(x0,y0);pDC->LineTo(x1,y1);pDC->LineTo(x2,y2);pDC->SelectObject(old);ReleaseDC(pDC);}由以上代码绘出的图形如下:2、利用Bezier曲线的生成算法实现二次Bezier曲线的生成(算法的详细原理见教材)。
实验三 Bezier曲线生成一、实验目的1. 理解并会自己编程实现二维Bezier曲线的画图二、实验内容和要求1.选择自己熟悉的任何编程语言, 建议使用VB,VC或JAVA。
2.创建良好的用户界面,包括菜单,参数输入区域和图形显示区域。
3.实现二维2、3、4阶Bezier曲线的描画。
4.将生成算法以菜单或按钮形式集成到用户界面上。
5.坐标参数可以用鼠标或键盘输入。
三.实验报告1.用户界面的设计思想和框图。
2.各种实现算法的算法思想。
3.算法验证例子。
4.上交源程序。
四.Bezier曲线生成程序设计的步骤如下:1.创建工程名称为“Test”单文档应用程序框架(1)启动VC,选择“文件”|“新建”菜单命令,并在弹出的新建对话框中单击“工程”标签。
(2)选择MFC AppWizard(exe),在“工程名称”编辑框中输入“Test”作为工程名称,单击“确定”按钮,出现Step 1对话框。
(3)选择“单个文档”选项,单击“下一个”按钮,出现Step 2对话框。
(4)接受默认选项,单击“下一个”按钮,在出现的Step 3~Step 5对话框中,接受默认选项,单击“下一个”按钮。
(5)在Step 6对话框中单击“完成”按钮,即完成“Test”应用程序的所有选项,随后出现工程信息对话框(记录以上步骤各选项选择情况),如图1-2所示,单击“确定”按钮,完成应用程序框架的创建。
图1-2 信息程序基本2.编辑菜单资源设计如图1-1所示的菜单项。
在工作区的ResourceView标签中,单击Menu项左边“+”,然后双击其子项IDR_MAINFRAME,并根据表1-1中的定义编辑菜单资源。
此时VC已自动建好程序框架,如图1-2所示。
表1-1菜单资源表3.添加消息处理函数利用ClassWizard(建立类向导)为应用程序添加与菜单项相关的消息处理函数,ClassName栏中选择CTestView,根据表1-2建立如下的消息映射函数,ClassWizard会自动完成有关的函数声明。
实验5 交互绘制Bezier曲线一、实验步骤1.打开Test工程试验框架。
2.窗口极大化显示方法:将Test.cpp文件的InitInstance()中的语句:m_pMainWnd->ShowWindow(SW_SHOW);改为:m_pMainWnd->ShowWindow(SW_MAXIMIZE);3.修改CTestView类(1)添加成员变量:方法:在工作区中选择ClassView类窗口,右击CTestView类,选择“Add Member Variable…”,定义如下的成员变量:protected:bool m_flag;// 鼠标绘图标志CPoint *pt;//顶点int CtrlPNum;//控制点个数(2)在“TestView.h”文件头添加如下预处理命令:#define N_MAX_POINT 10//控制多边形的最大顶点数(3)添加成员函数方法:在工作区中选择ClassView类窗口,右击CTestView类,选择“Add Member F unction…”,定义如下的成员函数:public:void DrawCtrPolygon();//绘制控制多边形void DrawBezier();//绘制Bezier函数long DeCasteliau(double,long *p);//德卡斯特里奥函数(4)按照教程130页编辑DeCasteliau(double,long *p)函数(5)按照教程131页编辑DrawBezier()函数(6)按照教程131页编辑DrawBezier()函数(7)按照教程131页编辑DrawCtrPolygon()函数4.按照教材38页添加WM_LBUTTONDOWN消息映射函数,并按照教程132页编辑5.添加WM_RBUTTONDOWN消息映射函数6.按照教材39页添加WM_MOUSEMOVE消息映射函数注意:(1)需要在“TestView.cpp”文件头加入下列命令:#include "MainFrm.h"//包含CMainFrame头文件,用于状态栏显示鼠标坐标位置(2)将文件“MainFrm.h”里的成员数据m_wndStatusBar属性修改为public(3)修改文件“MainFrm.cpp”中的indicators数组7.完善“绘图”子菜单消息处理函数,代码如下:void CTestView::OnDrawpic(){// TODO: Add your command handler code hereMessageBox("左键绘制控制多边形,右键绘制曲线","提示",MB_OK);pt=new CPoint [N_MAX_POINT];m_flag=TRUE;//可以使用鼠标绘制控制点CtrlPNum=0;//控制点初始个数为0}。
计算机图形学作业3姓名学号班级作业内容绘制一个“Bezier”曲线效果截图关键程序(<40行) #include<gl/glut.h>void Initial(void){glClearColor(0,0,0,0);glLineWidth(1);GLfloat ControlP[4][3]={{-66,-88,0},{-44,55,0},{22,-33,0},{77,66,0}};glMap1f(GL_MAP1_VERTEX_3,0,1,3,4,*ControlP);glEnable(GL_MAP1_VERTEX_3);}void Display(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1,0,0);glMapGrid1f(100,0,1);glEvalMesh1(GL_LINE,0,100);glFlush();}void Reshape(GLint newWidth,GLint newHeight){glViewport(0,0,newWidth,newHeight);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(-100,100,-100,100);}void main(){glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); //使用双缓存及RGB模型glutInitWindowSize(666, 488); //指定窗口的尺寸glutInitWindowPosition(288, 155); //指定窗口在屏幕上的位置glutCreateWindow("朱");Initial();glutDisplayFunc(Display);glutReshapeFunc(Reshape);glutMainLoop();}小结这一次的用OpenGL绘制贝塞尔曲线实验比上一次花了更长的时间,原来以为对OpenGL应该算是有了一些了解,这次实验过后发现,没搞明白的尚且有许多,更不用提还有许多根本不知道的应用方法。
三次贝塞尔曲线计算机图形学延安大学计算机学院实验报告专用纸一.实验目的熟悉三次贝塞尔曲线的生成算法,并能在TC环境下生成图形,并能熟悉四次贝塞尔曲线的生成,比较两者的异同。
二.实验内容三.实验环境Window某P;TC2.0;四.实验步骤①算法思想P0、P1、P2、P3四个点在平面或在三維空間中定義了三次方贝塞尔曲線。
曲線起始计算机图形学於P0走向P1,並從P2的方向來到P3。
一般不會經過P1或P2;這兩個點只是在那裡提供方向資訊。
P0和P1之間的間距,決定了曲線在轉而趨進P3之前,走向P2方向的。
曲线的参数形式为︰②具体代码#include"graphic.h"#include"math.h"main(){int某0=50,y0=300,某1=250,y1=150,某2=452,y2=150,某3=550,y3=300;int某,j,y,n=15;floati,dt,t;charmg[80];intgdriver=DETECT,gmode;regiterbgidriver(EGAVGA_driver);initgraph(&gdriver,&gmode,"c:\\TC");etbkcolor(2);etcolor(YELLOW);dt=1/(float)n;/某3_Bezier绘制曲线图某/for(i=0;i<=n;i++){t=i某dt;某=某0某(1-t)某(1-t)某(1-t)+某1某3某t某(1-t)某(1-t)+某2某3某t某t某(1-t)+某3某t某t某t;y=y0某(1-t)某(1-t)某(1-t)+y1某3某t某(1-t)某(1-t)+y2某3某t某t某(1-t)+y3某t某t某t;if(i==0)moveto(某,y);lineto(某,y);}line(某0,y0,某1,y1);line(某1,y1,某2,y2);line(某2,y2,某3,y3);printf(mg,"%%d%%d,%d%","P",0,"(",某0,y0,")");outte某t某y(某0,y0,mg);printf(mg,"%%d%%d,%d%","P",1,"(",某1,y1,")");outte某t某y(某1,y1,mg);printf(mg,"%%d%%d,%d%","P",2,"(",某2,y2,")");outte某t某y(某2,y2,mg);printf(mg,"%%d%%d,%d%","P",3,"(",某3,y3,")");outte某t某y(某3,y3,mg);getch();/某等待按一键结束某/计算机图形学cloegraph();/某关闭图形系统,回到文本模式某/}③实验结果。
实验5 Bezier曲线1.实验目的:了解曲线的生成原理,掌握几种常见的曲线生成算法,利用VC+OpenGL实现Bezier曲线生成算法。
2.实验内容:(1)结合示范代码了解曲线生成原理与算法实现,尤其是Bezier曲线;(2)调试、编译、修改示范程序。
(3)尝试实现B样条曲线算法。
3.实验原理:Bezier曲线是通过一组多边形折线的顶点来定义的。
如果折线的顶点固定不变,则由其定义的Bezier曲线是唯一的。
在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始处和终止处,其他的点用于控制曲线的形状及阶次。
曲线的形状趋向于多边形折线的形状,要修改曲线,只要修改折线的各顶点就可以了。
因此,多边形折线又称Bezier曲线的控制多边形,其顶点称为控制点。
三次多项式,有四个控制点,其数学表示如下:4.实验代码:#include <glut.h>#include <stdio.h>#include <stdlib.h>#include <vector>using namespace std;struct Point { int x, y; }; Point pt[4], bz[11];vector<Point> vpt;bool bDraw;int nInput;void CalcBZPoints(){float a0,a1,a2,a3,b0,b1,b2,b3;a0=pt[0].x;a1=-3*pt[0].x+3*pt[1].x;a2=3*pt[0].x-6*pt[1].x+3*pt[2].x;a3=-pt[0].x+3*pt[1].x-3*pt[2].x+pt[3].x;b0=pt[0].y;b1=-3*pt[0].y+3*pt[1].y;b2=3*pt[0].y-6*pt[1].y+3*pt[2].y;b3=-pt[0].y+3*pt[1].y-3*pt[2].y+pt[3].y;float t = 0;float dt = 0.01;for(int i = 0; t<1.1; t+=0.1, i++){bz[i].x = a0+a1*t+a2*t*t+a3*t*t*t;bz[i].y = b0+b1*t+b2*t*t+b3*t*t*t;}}void ControlPoint(vector<Point> vpt){ int i;glPointSize(2);for(i=0; i<vpt.size(); i++){glBegin (GL_POINTS);glColor3f (1.0f, 0.0f, 0.0f); glVertex2i (vpt[i].x,vpt[i].y);glEnd ();}}void PolylineGL(Point *pt, int num){glBegin (GL_LINE_STRIP);for(int i=0;i<num;i++){glColor3f (1.0f, 1.0f, 1.0f);glVertex2i (pt[i].x,pt[i].y);}glEnd ();}void myDisplay(){glClear(GL_COLOR_BUFFER_BIT);glColor3f (1.0f, 1.0f, 1.0f);if (vpt.size() > 0) {ControlPoint(vpt);}if(bDraw){PolylineGL(pt, 4);CalcBZPoints();PolylineGL(bz, 11);}glFlush();}void Init(){ glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_SMOOTH);printf("Please Click left button of mouse to input control point of Bezier Curve!\n");}void Reshape(int w, int h){glViewport(0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);}void mouse(int button, int state, int x, int y){switch (button){case GLUT_LEFT_BUTTON:if (state == GLUT_DOWN){if (nInput == 0){pt[0].x = x;pt[0].y = 480 - y;nInput = 1;vpt.clear();vpt.push_back(pt[0]);bDraw = false;glutPostRedisplay();//}else if (nInput == 1){pt[1].x = x;pt[1].y = 480 - y;vpt.push_back(pt[1]);nInput = 2;glutPostRedisplay();//}else if (nInput == 2){pt[2].x = x;pt[2].y = 480 - y;vpt.push_back(pt[2]);nInput = 3;glutPostRedisplay();//}else if (nInput == 3){pt[3].x = x;pt[3].y = 480 - y;bDraw = true;vpt.push_back(pt[3]);nInput = 0;glutPostRedisplay();//}}break;default:break;}}int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(640, 480);glutCreateWindow("Hello World!");Init();glutDisplayFunc(myDisplay);glutReshapeFunc(Reshape);glutMouseFunc(mouse);glutMainLoop();return 0;}。
程序课程设计报告2012年7月11日Bezier方法与吉祥物图案设计专业:信息与计算科学班级:信10-1吉祥物文洛克的设计题目: Bezier方法与吉祥物图案设计组长:石玮lun组员:张益、李天宇指导教师:张彩霞时间:19周——21周摘要:本文对Bezier曲线及其性质进行研究,利用Matlab软件对吉祥物——文洛克进行Sobel算子边缘提取工作,之后进行找点,通过Matlab描点绘制吉祥物——文洛克的边缘。
在众多的课题中,我们一眼就挑中了这个课题,因为我们觉得这项课题可能非常有意思,经过我们深入的研究,发现贝赛尔曲线很适合用来在电脑上绘制图形,用起来非常方便。
贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一。
阐述了Bezier方法在绘图上的应用, Bezier曲线具有良好的几何性质,能简洁、完美地描述和表达曲面。
Abstract:In this paper, the Bezier curve and the nature of the study, use of Matlab software on the rock-mascot Sobel operator edge extraction work, after find some, through the Matlab draw some draw the edge of rock-the mascot. In many of the topic, we immediately singled out on the subject, because we feel that the subject may be very interesting, through our in-depth research, found beisaier curve is used to draw on the graphics on a computer, use rise very convenient.Bezier computer graphics image is the basic tool modelling, is using the most graphic modelling is one of the basic line. Describes the method of drawing in Bezier application, Bezier curve has good geometrical properties, can concise, perfect to describe and express surface.关键词: Bezier曲线造型边缘提取曲面 Sobel算子Keywords:Bezier curve modeling Edge extraction curved surface Sobel operator1.引言曲线的表示是计算机图形学的重要内容,它是描述物体的外形,建立所画对象的数学模型的有力工具。
VC实现贝塞尔曲线绘制摘要:本文主要通过对Bezier曲线的几何图形的进一步理解,探讨其具体的控制方法,结合具体绘制实际分析理论描述对控制点计算理解的偏差,统一了认识;结合曲线绘制函数PolyBezier()具体的要求,实现VC环境下简单的曲线绘制方法研究。
关键词:贝塞尔曲线;PolyBezier;曲线连续性1贝塞尔曲线描述贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度。
所以本函数的顶点数组的记录方式是:控制点+顶点+控制点+控制点+顶点+控制点+……。
所以两个顶点之间的曲线是由两个顶点以及两个顶点之间的控制点来决定的。
一条贝塞尔样条由4个定义点定义:两个端点和两个控制点。
2曲线的绘制方法2.1PolyBezier函数PolyBezier函数用于画贝赛尔样条曲线,原型:BOOL PolyBezier (HDC,hdc,CONST POINT *lppt,DWORD cPoints);参数:hdc:指定的设备环境句柄。
Lppt:POINT结构数组的指针,包括了样条端点和控制点的坐标、其顺序是起点的坐标、起点的控制点的坐标、终点的控制点的坐标和终点的坐标。
cPoints:指明数组中的点的个数。
本文中绘制曲线主要用到这个函数。
2.2一阶连续性图1所示为一段Bezier曲线经过p0、p1两个端点,要绘制经过它们的曲线需要再确定k1、K2两个控制点,这条曲线最终是由p0、k1、k2、p1四个点决定。
图2为经过p0、p1(p2)、p3的一段连续曲线,可以看出,它是由p0-p1及p2-p3两段曲线组成,连续的贝塞尔曲线会把前一个终止点当作起始点:即p1=p2。
要绘制如图2所示曲线,关键在于确定k0、k1、k2、k3四个控制点方法,一般是根据两段曲线连续(即一阶连续性:两个相邻曲线段在交点处有相同的一阶导数)条件来得出。
总的来说,就是k0p0 连线即为曲线在p0处切线,k1p1连线为p1处切线,k24p2为p2处切线,k3p3为p3处切线,两段曲线连续必然要求k1p1与k2p2在一条线上。
贝塞尔曲面的拼接研究2012 年 1 月Bezier曲线的连接及Bezier曲面的拼接摘要根据线动成面的思想由Bezier曲面的概念引入Bezier曲面的概念,Bezier 实际上是先由控制顶点生成一个方向(设为v方向)上的Bezier曲线,然后在已竟形成的Bezier曲线上寻找控制顶点,生成另一个方向(设为u方向)上的Bezier曲线,形成控制网格,Bezier曲面是对该控制网格的逼近。
同样,类似于Bezier曲线的性质介绍了Bezier曲面的端点性质、边界线位置、凸包性等比较常见的几个性质。
几何设计中,一条Bezier曲线往往难以描述复杂的曲线形状。
这是由于增加特征多边形的顶点数,会引起Bezier曲线次数的提高,而高次多项式又会带来计算上的困难,实际使用中,一般不超过10次。
所以有时采用分段设计,然后将各段曲线相互连接起来。
同样的,复杂的曲面用Bezier曲面相互拼接起来实现。
根据光滑连续性的条件考虑连接处的光滑,从而实现Bezier曲线的光滑连接以及Bezier曲面的拼接。
关键词:光顺连续性、Bezier曲线的连接、Bezier曲面的拼接、服装仿真1 引言在虚拟现实和视景仿真应用中,天空仿真是必不可少的内容。
无论是地面还是空中、海上的视景仿真,天空背景的真实感对用户来说能大大提高视觉享受和沉浸感。
但是就目前来看,大部分软件和仿真平台对真实天空的模拟还都不太尽人意,例如著名的VEGA 仿真平台,不同气候条件下的天空仅仅是在不同颜色背景下几层贴上云纹理的平面,从地面上看去,云层明显的有一条水平的终结线。
而一旦进入这些云层,就更加明显的感到是穿过了几层毫无体积感的纹理平面。
在现实生活中,人们对天空是再熟悉不过了。
真实的天空是非常复杂的,从视觉角度分析,就有霞、雾、晕、晴、阴等等各种自然现象,而且整个天球在空间上也不是均匀体现某种颜色的,而是随着每天时间和天气状况的不同,有着千变万化的变化。
所以要完全仿真真实的天空,不仅要有图形学方面的知识,还要具备天文和大气物理学的知识,由于我们对这些知识不甚了了,只能对天空的仿真进行简化。
实验三贝齐尔(Bezier)曲线曲面的生成方法实验类型:综合型一、目的与任务目的:通过学生上机,了解贝齐尔(Bezier)曲线德卡斯特里奥的递推算法和贝齐尔(Bezier)曲线的几何作图法。
任务:熟悉线框建模、表面建模的基本方法。
二、内容、要求与安排方式1、实验内容与要求:贝齐尔(Bezier)曲线曲面的德卡斯特里奥的递推算法P(t)=∑Bi,n(t)Q(i)和几何作图法;要求用熟悉的编程语言编制、调试和运行程序,并打印程序清单和输出结果。
2、实验安排方式:课外编写好程序清单,按自然班统一安排上机。
三、实验步骤1、熟悉贝齐尔(Bezier)的贝齐尔基函数和贝齐尔的性质2、贝齐尔(Bezier)曲线的德卡斯特里奥的递推算法;3、贝齐尔(Bezier)曲线的几何作图法;4、贝齐尔(Bezier)曲线的德卡斯特里奥的递推算法;5、贝齐尔(Bezier)曲线的几何作图法。
6、对几何作图法绘制出图,对德卡斯特里奥的递推算法编出程序。
四、实验要求1.在规定的时间内完成上机任务。
2.必须实验前进行复习和预习实验内容。
3.在熟悉命令过程中,注意相似命令在操作中的区别。
4.指定图形完成后,需经指导教师认可后,方可关闭计算机。
5.完成实验报告一份。
五、试验具体内容1,Bezier 曲线的描述在空间给定n + 1 个点P0 ,P1 ,P2 , ⋯,Pn ,称下列参数曲线为n 次的Bezier 曲线。
P(t) = 6nt = 0PiJ i ,n (t) , 0 ≤t ≤1其中J i ,n (t) 是Bernstein 基函数,即B i ,n (t) = n !/i !(n - i) *t(1-t);i = 0 , ⋯⋯,n一般称折线P0P1P2 ⋯Pn 为曲线P(t) 的控制多边形;称点P0 ,P1 ,P2 , ⋯,Pn 为P(t) 的控制顶点。
在空间曲线的情况下,曲线P(t) = (x(t) ,y(t) ,z (t) ) 和控制顶点Pi = (Xi ,Yi ,Zi) 的关系用分量写出即为:X(t) = 6ni = 0XiJ i ,n (t)Y(t) = 6ni = 0YiJ i ,n (t)Z(t) = 6ni = 0ZiJ i ,n (t)当t 在区间[0 ,1 ] 上变动时,就产生了Bezier 曲线。
计算机图形学实验报告专业:信息与计算科学班级: 1002班学号: **********姓名: ****实验目的:(1)掌握直线的参数表示法。
(2)掌握德卡斯特里奥算法的几何意义。
(3)掌握绘制二维Bezier曲线的方法。
实验要求:(1)使用鼠标左键绘制个数为10以内的任意控制点,使用直线连接构成控制多边形。
(2)使用鼠标右键绘制Bezier曲线。
(3)在状态栏显示鼠标的位置坐标。
(4)B ezier曲线使用德卡斯特里奥算法绘制。
实验算法:Bezier曲线的分割递推德卡斯特里奥算法给定空间n+1个点P i(i=0,1,2,…,n)及参数t,有P r i(t)=(1-t)P1-r i(t)+t P1-r1i+(t)式中,r=1,2,…,n;i=0,1,…,n-r;t∈[0,1]。
且规定当r=0时,P0i(t)=P i, P n0(t)是在曲线上具有参数t的点。
德卡斯特里奥算法的基础就是在矢量−−→−PP10上选择一个点P,使得P点划分矢量−−→−PP10为|PP0|:|PP1|=t:1-t,给定点P0、P1的坐标以及t的值,点P的坐标为P=P0+t(P1-P0)=(1-t)P0+tP1。
式中,t∈[0,1]。
定义贝塞尔曲线的控制点编号为P r i,其中,r表示迭代次数。
德卡斯特里奥证明了,当r=n时,P n0表示Bezier曲线上的点。
函数功能介绍1.德卡斯特里奥函数:long CMy12View::DeCasteliau(double t,long *p){double P[N_MAX_POINT][N_MAX_POINT];int n=CtrlPNum-1;for(int k=0;k<=n;k++){P[0][k]=p[k];}for(int r=1;r<=n;r++){for(int i=0;i<=n-r;i++){P[r][i]=(1-t)*P[r-1][i]+t*P[r-1][i+1];}}return(long(P[n][0]));}函数功能介绍:此函数为德卡斯特里奥算法函数。
1贝齐尔曲面设计 1.1 贝齐尔曲面定义设),1,0;,1,0(m j n P ij =为)1()1(+⨯+m n 个空间点列,则m ×n 次Bezier 曲面定义为:]1,0[,)()(),(00,,∈=∑∑==v u v B u B P v u P m i nj n j m i ij (式2-1)其中im ii m m i u u C u B --=)1()(, ,jn j j n n i v v C v B --=)1()(,是Bernstein 基函数。
依次用线段连接点列中相邻两点所形成的空间网格,称之为特征网格。
Bezier 曲面的矩阵表示式是:[]⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡=)()()()(,),(),(),(,,1,0101111000100,,1,0v B v B v B P P P P P PP P P u B u B u B v u P m n m m nm n n m m n m n n (式2-2)在一般实际应用中,n 、m 不大于4。
(1) 双线性Bezier 曲面 当m=n=1时∑=∑==1010)()(),(1,1,i j p w B u B w u S ijj i u ,w ∈[0,1] (式2-3)定义一张双线性Bezier 曲面。
已知四个角点之后,则11100100)1()1()1)(1(),(uwpup w p u u w w u S -+-+--= (式2-4)(2) 双二次Bezier 曲面 当m=n=2时∑∑===2022,2,)()(w)S(u,i j ijj i p w B u B ]1,0[,∈w u (式2-5)由此式定义的曲面,其边界曲线及参数坐标曲线均为抛物线。
(3) 双三次Bezier 曲面 当m=n=3时∑∑===3033,3,)()(w)S(u,i j ijj i p w B u B ]1,0[,∈w u (式2-6)⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡=)()()()()]()()()([),(3,33,23,13,0333231302322212013121110030201003,33,23,13,0w B w B w B w B p p p p p p p p p p p p p p p p u B u B u B u B w u S (式2-7)其矩阵表示为TTZ Z Z W M B UM w u S =),(⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎣⎡----===0001003303631331],1[],1[2323z M w w w W u u u U (式2-8)1.2 贝齐尔曲面性质1.Bezier 曲面特征网格的四个角点正好是Bezier 曲面的四个角点,即P(0,0)=P00 P(1,0)=PM0 P(0,1)=P0N P(1,1)=PMN 2. Bezier 曲面特征网格最外一圈顶点定义Bezier 曲面的四条边界;Bezier 曲面边界的跨界切矢只能与定义该边界的顶点及相邻一排顶点有关,且P00P10P01, P0nP1nP0,n-1, Pm0Pm-1,0Pm1,分别是四个角点的切平面;跨界二阶导矢只与定义该边界的及相邻两排顶点有关。
Bezier曲线的绘制实验报告 一、程序实现环境 1操作系统:Windows XP 、Windows7 2.编程语言:C++ 3.程序实现环境:Visual C++ 6.0 二、算法思想
三、使用说明 程序界面如下图:
用户可以在编辑框中输入4个控制点的坐标,也可以通过在绘图区内直接通过鼠标的单击指定4个控制点的位置,输入4个控制端点后,单击“画Bezier曲线”按钮即可绘制Bezier曲线。 四、实验结果
五、程序代码(关键代码) void CMFC_BezierCurve2Dlg::OnLButtonDown(UINT nFlags, CPoint point) { if(pointOrd==1) //原点(490,270) { m_p1_x = point.x - 490; m_p1_y = 270 - point.y; } if(pointOrd==2) { CDC *pDC=GetDC(); pDC->MoveTo(490+m_p1_x, 270-m_p1_y); pDC->LineTo(point.x, point.y);
m_p2_x = point.x - 490; m_p2_y = 270 - point.y; } if(pointOrd==3) { CDC *pDC=GetDC(); pDC->MoveTo(490+m_p2_x, 270-m_p2_y); pDC->LineTo(point.x, point.y);
m_p3_x = point.x - 490; m_p3_y = 270 - point.y; } if(pointOrd==4) { CDC *pDC=GetDC(); pDC->MoveTo(490+m_p3_x, 270-m_p3_y); pDC->LineTo(point.x, point.y);
m_p4_x = point.x - 490; m_p4_y = 270 - point.y; } pointOrd++; UpdateData(FALSE);
CDialog::OnLButtonDown(nFlags, point); }
voidGetCnk (int n, int *c) { inti,k; for(k=0; k<=n; k++) { c[k]=1; for(i=n; i>=k+1; i--) c[k]=c[k]*i; for(i=n-k; i>=2; i--) c[k]=c[k]/i; } }
void CMFC_BezierCurve2Dlg::GetPointPos(intControlN, double t, int *c) { int k, n=ControlN-1; double Bernstein; Pt.x=0.0; Pt.y=0.0; for(k=0; k{ Bernstein=c[k]*pow(t,k)*pow(1-t,n-k); Pt.x += ControlP[0][k].x * Bernstein; Pt.y += ControlP[0][k].y * Bernstein; } }
void CMFC_BezierCurve2Dlg::OnButtonDrawBeziercurve() { UpdateData(); pointOrd=1; CDC *pDC=GetDC(); ControlP[0][0].x=m_p1_x;ControlP[0][0].y=m_p1_y; ControlP[0][1].x=m_p2_x;ControlP[0][1].y=m_p2_y; ControlP[0][2].x=m_p3_x;ControlP[0][2].y=m_p3_y; ControlP[0][3].x=m_p4_x;ControlP[0][3].y=m_p4_y;
pDC->MoveTo(490+m_p1_x, 270-m_p1_y); pDC->LineTo(490+m_p2_x, 270-m_p2_y); pDC->LineTo(490+m_p3_x, 270-m_p3_y); pDC->LineTo(490+m_p4_x, 270-m_p4_y); int *C, i; intControlN=4, m=500; C=new int[ControlN]; GetCnk (ControlN-1, C); for(i=0; i<=m; i++) { GetPointPos(ControlN, (double)i/(double)m, C); pDC->SetPixel(490+Pt.x, 270-Pt.y, 255); } } 两段Bezier曲线的拼接实验报告 一、程序实现环境 1操作系统:Windows XP 、Windows7 2.编程语言:C++ 3.程序实现环境:Visual C++ 6.0 二、算法思想
三、使用说明 程序界面如下图:
用户可以在编辑框中输入4个控制点的坐标,也可以通过在绘图区内直接通过鼠标的单击指定4个控制点的位置,输入4个控制端点后,单击“画Bezier曲线”按钮即可绘制Bezier曲线。 分别绘制完两段Bezier曲线后,单击拼接即可实现两段曲线的拼接。 四、实验结果 五、程序代码(关键代码) void CMFC_BezierCurve2Dlg::OnLButtonDown(UINT nFlags, CPoint point) { if(pointOrd==1) //原点(490,270) { m_p1_x = point.x - 490; m_p1_y = 270 - point.y; } if(pointOrd==2) { CDC *pDC=GetDC(); pDC->MoveTo(490+m_p1_x, 270-m_p1_y); pDC->LineTo(point.x, point.y);
m_p2_x = point.x - 490; m_p2_y = 270 - point.y; } if(pointOrd==3) { CDC *pDC=GetDC(); pDC->MoveTo(490+m_p2_x, 270-m_p2_y); pDC->LineTo(point.x, point.y); m_p3_x = point.x - 490; m_p3_y = 270 - point.y; } if(pointOrd==4) { CDC *pDC=GetDC(); pDC->MoveTo(490+m_p3_x, 270-m_p3_y); pDC->LineTo(point.x, point.y);
m_p4_x = point.x - 490; m_p4_y = 270 - point.y; }
pointOrd++; UpdateData(FALSE);
CDialog::OnLButtonDown(nFlags, point); }
voidGetCnk (int n, int *c) { inti,k; for(k=0; k<=n; k++) { c[k]=1; for(i=n; i>=k+1; i--) c[k]=c[k]*i; for(i=n-k; i>=2; i--) c[k]=c[k]/i; } }
void CMFC_BezierCurve2Dlg::GetPointPos(intControlN, double t, int *c) { int k, n=ControlN-1; double Bernstein; Pt.x=0.0; Pt.y=0.0; for(k=0; k{ Bernstein=c[k]*pow(t,k)*pow(1-t,n-k); Pt.x += ControlP[pointGroup][k].x * Bernstein; Pt.y += ControlP[pointGroup][k].y * Bernstein; } }
void CMFC_BezierCurve2Dlg::BezierCurve() { CDC *pDC=GetDC(); pDC->MoveTo(490 + ControlP[pointGroup][0].x, 270 - ControlP[pointGroup][0].y); pDC->LineTo(490 + ControlP[pointGroup][1].x, 270 - ControlP[pointGroup][1].y); pDC->LineTo(490 + ControlP[pointGroup][2].x, 270 - ControlP[pointGroup][2].y); pDC->LineTo(490 + ControlP[pointGroup][3].x, 270 - ControlP[pointGroup][3].y);
int *C, i; intControlN=4, m=500; C=new int[ControlN]; GetCnk (ControlN-1, C); for(i=0; i<=m; i++) { GetPointPos(ControlN, (double)i/(double)m, C); pDC->SetPixel(490+Pt.x, 270-Pt.y, 255); } }
void CMFC_BezierCurve2Dlg::OnButtonDrawBeziercurve() { UpdateData(); pointOrd=1;
ControlP[pointGroup][0].x=m_p1_x; ControlP[pointGroup][0].y=m_p1_y; ControlP[pointGroup][1].x=m_p2_x; ControlP[pointGroup][1].y=m_p2_y; ControlP[pointGroup][2].x=m_p3_x; ControlP[pointGroup][2].y=m_p3_y; ControlP[pointGroup][3].x=m_p4_x; ControlP[pointGroup][3].y=m_p4_y;
BezierCurve(); pointGroup++; }
void CMFC_BezierCurve2Dlg::OnButtonMatch() { pointGroup--;
double dx, dy; double k1, k2, s, s1, s2; int i; CPoint temp;