实验四 自由曲线曲面算法实验(2)
实验四 曲线生成算法

实验四曲线生成算法一、目的和要求(1)根据曲线的基础知识和常用曲线的数学基础,对其算法进行程序设计,验证算法的正确性,并通过程序结果加深对常用曲线数学模型的理解。
;(2)写出Bezier曲线的算法实现;(3)写出B样条曲线的算法实现;二、实验内容(一)Bezier曲线的算法实现1、建立一个BezierCurve的工程文件:2、右击CBezierCurveView类,建立成员函数:int CBezierCurveView::Multiply_n(int m, int n)用于的函数实现:!!!()!double CBezierCurveView::Bernstein(int m, int n, double t)用于实现伯恩斯坦多项数的函数实现:,()3、编写自定义的成员函数代码:(注意:程序灰色底纹部分为自己添加,没有底纹的为工程文件自动生成。
)int CBezierCurveView::Multiply_n(int m, int n){int i,j,a;if(m!=0){a=1;for(i=m+1;i<=n;i++)a=a*i;for(j=1;j<=n-m;j++)a=a/j;return a;}elsereturn 1;}double CBezierCurveView::Bernstein(int m, int n, double t) {int i,j;double sum;sum=Multiply_n(m,n);for(i=1;i<=m;i++)sum=sum*t;for(j=1;j<=n-m;j++)sum=sum*(1-t);return sum;}4、编写OnDraw()函数:void CBezierCurveView::OnDraw(CDC* pDC){CBezierCurveDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereint i,j,k,n=3;double curx,cury,t,b;double dt=0.01;int array[4][2]={{30,100},{100,30},{50,150},{200,40}};CPen PenRed(PS_SOLID,1,RGB(255,0,0));//定义红色笔CPen PenBlue(PS_SOLID,1,RGB(0,0,255));//定义蓝色笔//绘制特征多边形pDC->SelectObject(&PenBlue);pDC->MoveTo(array[0][0],array[0][1]);for(i=0;i<=n;i++)pDC->LineTo(array[i][0],array[i][1]);//绘制Bezier曲线pDC->MoveTo(array[0][0],array[0][1]);pDC->SelectObject(&PenRed);t=0.0;for(i=0;i<=(int)1/dt;i++){curx=0;cury=0;for(j=0;j<=n;j++){b=Bernstein(j,n,t);curx=curx+array[j][0]*b;cury=cury+array[j][1]*b;}pDC->LineTo(curx,cury);t=t+dt;}}5、编译、调试和运行程序,程序结果如下:6、尝试修改特征多边形的顶点,生成其他形状的Bezier曲线。
自由曲线

设有N个型值点P1 P2…PN,相邻三点做 一抛物线,可共做N-2条曲线段,第i条抛 物线的表达式用Si(ti)表示。 由Pi Pi+1 Pi +2三点构成
Si (ti ) a iti biti ci
2
t i [ 0 ,1]
第i+1条抛物线的表达式用S i+1(t i+1 )表示。 由Pi+1 Pi +2 Pi +3三点构成
3 2 2 3
2
3
其中,tj=jdt,dt=0.5/m ,m为曲线段内插值所走的步数,j=1~m。
输入Pi~Pn个型值点的值
曲线完成 曲线段循环i=1~n-3
画曲线段的起点Pi
结束
曲线段内插值循环 For j=1~m
画曲线段完成
计算t j = j d t
计算P=S(t j) 强制画线到曲线 段的终点Pi+2
moveto(p1x,p1y); for(i=0;i<=n;i++) { f1=(1.0-d1)*(1.0-d1)*(1.0-d1); f2=3.0*d1*(1.0-d1)*(1.0-d1); f3=3.0*d1*d1*(1.0-d1); f4=d1*d1*d1; x=f1*p1x+f2*p2x+f3*p3x+f4*p4x; y=f1*p1y+f2*p2y+f3*p3y+f4*p4y; lineto((int)x,(int)y); d1+=d;} getch(); closegraph(); }
t [ 0 ,0 .5 ]
将a,b,c的求值代入上式,经整理
n-3 n 1
S(t)
( 4 t t 4 t ) P i (1 10 t 12 t ) P i 1
计算机图形学-自由曲线与曲面2

哈工大计算机学院 苏小红
22
Bezier曲线(22/22)
• 缺点:
– 所生成的曲线与特征多边形的外形相距较远 – 局部控制能力弱,因为曲线上任意一点都是所有给
定顶点值的加权平均 – 控制顶点数增多时,生成曲线的阶数也增高 – 控制顶点数较多时,多边形对曲线的控制能力减弱 – 曲线拼接需要附加条件,不太灵活
• 苏晓红,李东,王宇颖.基于曲率参数的NURBS曲线插值 .哈尔滨工业大学学报,2001,1,33(1):108-111
哈工大计算机学院 苏小红
44
B样条曲线(19/19)
• 优点:
– 与控制多边形的外形更接近 – 局部修改能力 – 任意形状,包括尖点、直线的曲线 – 易于拼接 – 阶次低,与型值点数目无关,计算简便
– 第2段:
P2, P3, …, Pn, Pn+1, Pn+2
– 第m段:
Pm, …, Pn+m-1, Pn+m
哈工大计算机学院 苏小红
27
B样条曲线(4/19)
• 为简化记号,取i=0来代表样条中的任意一段
• 基函数为B样条函数
规定0/0=0
哈工大计算机学院 苏小红
28
B样条曲线(4/19)
• deboor-Cox 递归公式
第四章 自由曲线与曲面(二)
第四章 曲线与曲面
• 概述 • 参数曲线基础 • 参数多项式曲线 • 三次Hermite曲线 • Bezier曲线 • B样条曲线
哈工大计算机学院 苏小红
2
外形设计的要求与特点
• 初始给定的型值点不精确,不必点点通过 • 性能、美观、自由度大 • 想想画家是如何画汽车的?
上机实验4:自由曲线和曲面的绘制

计算机图形学课程实验 报 告实验题目 自由曲线和曲面的绘制 班 级 计算081 姓 名 杨 恒 学 号 3080811017 指导教师 胡钢 日 期 2011.6.3西安理工大学理学院应用数学系二零一一年春季学期信息与计算科学专业基础课 Computer GraphicsReport Of course experiment实验说明实验目的:掌握自由曲线和曲面(包括Bezier 曲线、曲面和B 样条曲线、曲面)的生成算法思想,并能上机编程绘制相应的曲线、曲面和利用曲线、曲面进行简单的几何造型设计。
实验地点: 教九楼401 数学系机房实验要求(Direction): 1.每个学生单独完成;2.开发语言为TurboC 或C++,也可使用其它语言;3.请在自己的实验报告上写明姓名、学号、班级;4.每次交的实验报告内容包括:题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;5. 自己保留一份可执行程序,考试前统一检查和上交。
实验内容实验题一1.1实验题目上机编写一个能绘制Bezier 曲线和B 样条曲线的通用程序,并调试成功。
具体要求为:(1)用户在运行程序时,可以根据提示信息来决定选择绘制Bezier 曲线,还是B 样条曲线;(2)两种曲线控制顶点的个数和坐标值要求可以随机输入(即Bezier 曲线和B 样条曲线的次数和位置可以随机输入);(3)当用户输入控制点的坐标位置后,屏幕上生成曲线的同时显示其特征多边形;且在特征多边形的顶点处输出该顶点坐标;(4)要求在可执行程序后附上运行结果(两种曲线都至少附上一个结果图)。
自由曲线和曲面的绘制实验41.2实验目的和意义掌握Bezier曲线和B样条曲线的绘制方法。
1.3程序制作步骤(包括算法的基本思想、流程图、设计步骤等)一、基本思想(1)Bezier曲线:是由一组折线来定义的,且第一个点和最后一个点在曲线上,第一条和最后一条折线分别表示出曲线在起点和终点处的切线方向。
第4章 自由曲线与曲面2[52页]
![第4章 自由曲线与曲面2[52页]](https://img.taocdn.com/s3/m/5a9b4f5902020740bf1e9b14.png)
3
Bezier曲线
• 1962年,法国雷诺汽车公司,P.E.Bezier工程师 • 以“逼近”为基础 • UNISURF • 1972年雷诺汽车公司正式使用 • 稍早于Bezier,法国雪铁龙汽车公司,de Casteljau • Flash的绘图工具 • 北大方正,字型的轮廓线
11
Bezier曲线(11/22)
– 拟局部性
– 形状的易控性(演示)
哈工大计算机学院 苏小红
12
Bezier曲线(12/22)
• 二次Bezier曲线
– n=2 – 抛物线
P1
P(0.5)
基函数
P(0)
P0
M
P(1)
P2
哈工大计算机学院 苏小红
13
Bezier曲线(13/22)
• 三次Bezier曲线
哈工大计算机学院 苏小红
23
第四章 曲线与曲面
• 概述 • 参数曲线基础 • 参数多项式曲线 • 三次Hermite曲线 • Bezier曲线 • B样条曲线
哈工大计算机学院 苏小红
24
B样条曲线(1/19)
• 产生:
– 1946年,Schoenberg发表关于B样条函数的第1篇论文 – 1973年前后,Gordon,Riesenfield,Forrest等人受到Bezier方法的启
(t
)
C30 (1 t)3
1 3 3 1 1
GBEZ
•
C31t(1
t
)2
C32tC2 (331t3
t
)
GBEZ
•
0 0 0
3 0 0
6
3
t
3 3t2
自由曲线与曲面-123页精选文档

每种描述是一个带有某特定边界条件多项式的特殊 类型。
02.12.2019
5
例如空间一条曲线用三次参数方程可以表示如下:
x(u)﹦axu 3﹢bxu 2﹢cxu﹢dx y(u)﹦ayu 3﹢byu 2﹢cyu﹢dy z(u)﹦azu 3﹢bzu 2﹢czu﹢dz u[0,1] 或
二阶几何连续性,记为G2连续,指两个曲线段在相交 处其一阶和二阶导数均成比例。G2连续下,两个曲线段在 交点处的曲率相等。
02.12.2019
4
7.1.4 参数样条曲线 1.样条曲线
在计算机图形学中,术语样条曲线指由多项式曲 线段连接而成的曲线,在每段的边界处满足特定连 续条件。而样条曲面可用两组正交样条曲线来描述。 样条用来设计曲线和曲面形状,典型的CAD应用包 括汽车、飞机和航天飞机表面设计以及船壳设计。
Hermite样条插值(以法国数学家Charles Hermite
命名)使用型值点和型值点处的一阶导数建立边界条
件。设Pk和Pk+1为第K个和第K+1个型值点,Hermite样 条插值边界条件规定为:
P(0) ﹦Pk P(1) ﹦Pk+1 P’(0)﹦Dk P’(1)﹦Dk+1 其中,Dk和Dk+1分别为Pk和Pk+1处的一阶导数。 将参数方程写成矩阵形式为:
﹢(-3xk﹢3xk+1-2xk'-xk+1')u2+xk'u﹢xk y(u)﹦(2yk-2yk+1+yk'﹢yk+1')u3
﹢(-3yk﹢3yk+1-2yk'-yk+1')u2+yk'u﹢yk z(u)﹦(2zk-2zk+1+zk'﹢zk+1')u3
自由曲线曲面造型技术

2、简单技术 (插值与拟合)
2.1曲 线 拟 合 问 题 的 提 法
已知一组(二维)数据,即平面上 n个点(xi,yi) i=1,…n, 寻求一个函数(曲线)y=f(x), 使 f(x) 在某种准则下与所 有数据点最为接近,即曲线拟合得最好。
y
+
+
+
+ + (xi +i,yi)
+
+
y=f(x) +
但人们并不安于现状,继续探索新的造型方法。相继 出现了自由变形造型、偏微分方程造型、能量法造型、 小波技术等。这些方法目前还处于深入研究阶段,有 望于21世纪得到广泛的应用。
插值(interpolation)、拟合(fitting)和
逼近(approximation),一直是曲线曲面 造型基本的方法。
问题:给定一批数据点,需确定满足特定要求的曲线或曲面 解决方案: •若要求所求曲线(面)通过所给所有数据点,就是插值问题; •若不要求曲线(面)通过所有数据点,而是要求它反映对象 整体的变化趋势,这就是数据拟合,又称曲线拟合或曲面拟合。
函数插值与曲线拟合都是要根据一组数据构造一个函数作 为近似,由于近似的要求不同,二者的数学方法上是完全不同 的。 实例:下面数据是某次实验所得,希望得到X和 f之间的关系?
4)线性插值
等等
样条插值
比分段线性插值更光滑。
y
a
xi-1 xi
bx
在数学上,光滑程度的定量描述是:函数(曲
线)的k阶导数存在且连续,则称该曲线具有k阶光
滑性。 光滑性的阶次越高,则越光滑。是否存在较低
次的分段多项式达到较高阶光滑性的方法?三次 样条插值就是一个很好的例子。
自由曲线的生成算法

实验四:实现自由曲线的生成算法一.实验目的:掌握计算机图形学中各种常见图形的各种算法及其实现。
特别要求直线,二次曲线,自由曲线,区域填充,二维图形裁剪,图形几何变换,自由曲面二.实验内容(1)巩固图形学中关于自由曲线的绘制算法;(2)编写程序实现Hermite,Bezier,B样条曲线个各一条;(3)综合利用直线,圆,自由曲线的算法设计生成一个卡通图形和或图案;注:本次实验要求不能直接使用系统提供的绘制二次曲线函数,但是可以调用相应的画点或画线函数。
三.实验原理使用VC环境开发实例步骤:打开VC++6.0运行界面;选择文件菜单—新建—工程—MFC App Wiaard[exe]:在右侧添加工程名称,单击确定。
单文档—点击完成,确定在View类中添加成员函数名(如:line);在新添加的函数(void CDDALineView::line())下添加程序实现过程;void CDDALineView::Ondraw(CDC*Pdc){CDDALineDoc=GetDocument();ASSERT_VALID(pDoc);//TODO:add draw code for native data hereline();}四.实验环境硬件环境:PIII以上,内存为128M以上PC机即可.软件环境:开发平台为Windows或DOS,开发语言为C或C++,可以使用其他编程语言,相关知识自学掌握。
五.实验方案利用计算机图形学中直线,圆弧的形成算法熟悉所使用的开发环境,能够利用C所提供的绘图函数自行编写一个程序,使用相关函数完成图形的初使化能够编写程序实现Hermite,Bezier,B样条曲线个各一条;六.实验步骤及实验结果Hermite曲线:void CMy050401huqingguo04View::Hermite(){CClientDC dc(this);dc.TextOut(150,70,"Hermite曲线");dc.TextOut(500,40,"实验4:实现自由曲线的生成算法");dc.TextOut(500,70,"班级:计算机0503");dc.TextOut(500,100,"姓名:方磊");dc.TextOut(500,130,"学号:7");CPen pen1,pen2;pen1.CreatePen(PS_SOLID,2,RGB(255,0,255));pen2.CreatePen(PS_SOLID,3,RGB(0,0,0));inta1[9][2]={100,300,120,200,220,200,270,100,370,100,420,200,420,300,220,28 0,100,300};inta2[9][2]={70,-70,70,-70,70,-70,70,-70,70,70,70,70,-70,70,-70,70,70,-70};for(int i=0;i<8;i++){dc.SelectObject(&pen1);dc.MoveTo(a1[i][0],a1[i][1]);dc.LineTo(a1[i+1][0],a1[i+1][1]);dc.MoveTo(a1[i][0],a1[i][1]);for(double u=0;u<1;u=u+0.01){ double x,y;x=(2*u*u*u-3*u*u+1)*a1[i][0]+(-2*u*u*u+3*u*u)*a1[i+1][0]+(u*u*u-2*u*u+u)*a2[i][0]+(u*u*u-u*u)*a2[i+1][0];y=(2*u*u*u-3*u*u+1)*a1[i][1]+(-2*u*u*u+3*u*u)*a1[i+1][1]+(u*u*u-2*u*u+u)*a2[i][1]+(u*u*u-u*u)*a2[i+1][1];dc.SelectObject(&pen2);dc.LineTo(x,y);Sleep(2);}dc.SelectObject(&pen1);}pen1.DeleteObject();pen2.DeleteObject();}Bezier曲线:void CMy050401hiqingguo04View::Bezier(){CClientDC dc(this);dc.TextOut(5,50,"由七个控制点绘制的Bezier曲线(心型结构),其中起始点和终止点相同");dc.TextOut(500,40,"实验4:实现自由曲线的生成算法");dc.TextOut(500,70,"班级:计算机0503");dc.TextOut(500,100,"姓名:方磊");dc.TextOut(500,130,"学号:7");CPen pen1,pen2;pen1.CreatePen(PS_SOLID,3,RGB(255,0,0));pen2.CreatePen(PS_SOLID,1,RGB(255,0,255));inta[7][2]={{300,220},{200,100},{100,250},{300,400},{500,250},{400,100},{3 00,220}};for (int i=0;i<4;i=i+3){dc.MoveTo(a[i][0],a[i][1]);dc.LineTo(a[i+1][0],a[i+1][1]);dc.LineTo(a[i+2][0],a[i+2][1]);dc.LineTo(a[i+3][0],a[i+3][1]);dc.MoveTo(a[i][0],a[i][1]);for (double u=0;u<1;u=u+0.01){double x,y;x=(-u*u*u+3*u*u-3*u+1)*a[i][0]+(3*u*u*u-6*u*u+3*u)*a[i+1][0] +(-3*u*u*u+3*u*u)*a[i+2][0]+u*u*u*a[i+3][0];y=(-u*u*u+3*u*u-3*u+1)*a[i][1]+(3*u*u*u-6*u*u+3*u)*a[i+1][1] +(-3*u*u*u+3*u*u)*a[i+2][1]+u*u*u*a[i+3][1];dc.SelectObject(&pen1);dc.LineTo(x,y);Sleep(20);}dc.SelectObject(&pen2);}pen1.DeleteObject();pen2.DeleteObject();}卡通图:void CMy050401hiqingguo04View::duck(){CClientDC dc(this);CPen pen1,pen2;pen1.CreatePen(PS_SOLID,2,RGB(0,255,0));pen2.CreatePen(PS_SOLID,2,RGB(0,0,0));int a[50][2]={180,200,190,130,235,120,280,135,300,150,320,185,310,200,300,240,260,285,230,290,255,285,300,290,320,293,360,310,400,310,480,270,435,320,410,340,380,380,370,400,330,420,300,420,240,420,210,410,170,350,160,310,140,290,180,235,170,232,160,234,140,236,138,235,138,234,140,233,155,228,160,226,180,220,160,220,150,222,130,220,128,219,128,217,130,216,160,210,170,205,180,200};//小鸭子的外型线框dc.SelectObject(&pen1);for(int i=0;i<=44;i=i+1){dc.MoveTo(a[i][0],a[i][1]);dc.LineTo(a[i+1][0],a[i+1][1]);}pen1.DeleteObject();//Bezier曲线dc.SelectObject(&pen2);dc.Arc(215,185,245,215,245,215,245,215);dc.Arc(228,198,232,202,232,202,232,202);dc.MoveTo(250,340);dc.LineTo(320,340);dc.MoveTo(250,350);dc.LineTo(320,350);dc.MoveTo(250,360);dc.LineTo(320,360);dc.Arc(230,310,330,390,330,285,330,400);for(i=0;i<=44;i=i+3){dc.MoveTo(a[i][0],a[i][1]);for(double u=0;u<1;u=u+0.01){double x,y;x=(-u*u*u+3*u*u-3*u+1)*a[i][0]+(3*u*u*u-6*u*u+3*u)*a[i+1][0]+(-3* u*u*u+3*u*u)*a[i+2][0]+u*u*u*a[i+3][0];y=(-u*u*u+3*u*u-3*u+1)*a[i][1]+(3*u*u*u-6*u*u+3*u)*a[i+1][1]+(-3*u*u*u+3*u*u)*a[i+2][1]+u*u*u*a[i+3][1];dc.LineTo(x,y);Sleep(1);}}pen2.DeleteObject();}。
自由曲面的CGH光学检测方法与实验

自由曲面的CGH光学检测方法与实验黎发志1,2,郑立功1,闫锋1,薛栋林1,张学军1【摘要】自由曲面能有效地简化光学系统结构并提高其性能,在照明光学系统和成像光学系统中均具有良好的应用前景。
为了实现自由曲面的高精度光学检测,分析了自由曲面的计算机全息图(CGH)检测方法并讨论了它的限制因素;探讨了使用基准CGH区域解决自由曲面检测时的对准问题;设计并制作了直径为180 mm的CGH对某三次方项波前编码自由曲面(口径150 mm,PV为6λ,λ@632.8 nm)进行了光学检测,该方法的检测结果(0.068λrms)与非零位检测方法的检测结果(0.067λrms)一致,实验验证了自由曲面的CGH检测方法。
该方法具有易对准、精度高和效率高的优点。
【期刊名称】红外与激光工程【年(卷),期】2012(041)004【总页数】5【关键词】计算全息图;自由曲面;光学检测0 引言自由曲面能有效地简化光学系统结构并提高系统光学性能,目前已经广泛应用到照明光学系统中以提高能量利用率和优化照明效果。
自由曲面应用到成像光学系统中能有效地扩大视场和减小像差[1]或附加特殊效果[2],具有良好的应用前景,然而由于成像光学系统中的自由曲面具有复杂面形且面形精度要求较高,给光学制造过程中的加工[3]和检测[4]带来困难,致使其应用大大受限。
目前,自由曲面制造过程中常用三坐标测量方法进行面形检测,该方法能测量几乎任何类型的自由曲面面形,但其精度有限,难以满足成像光学系统对自由曲面精度的需求。
莫尔法、条纹投影法也可以用来检测自由曲面,但同样存在精度不够高的问题。
非零位干涉检测方法也可用来检测某些自由曲面:采用数字样板技术可对与球面偏离量非常小的一类自由曲面进行非零位干涉检测[5];对于与球面偏离量较大的自由曲面,可以采用子孔径拼接技术,但其检测过程较为繁琐,且检测精度受限于拼接过程中的机械精度和拼接算法。
计算机全息图(CGH)常用来检测非球面[6-7],该技术可通过衍射从球面波生成几乎任何形状的参考波前,这一特点使得它可结合激光干涉仪对自由曲面进行零位补偿光学检测,同时具有高效率和高精度的优点。
图形学实验报告五 常用曲面与曲线的生成算法

贵州大学实验报告
学院:计算机科学与信息学院专业:计算机科学与技术班级:101记为:G=A•M
可将其简记为:
上式是三次Hermite(Ferguson)曲线的几何形式。
几何系数是P0、P1、P’0、P’1。
构成该Bézier曲线的特征多边形,
Bézier曲线
样条曲线
B样条基函数代替Bernstein
样条曲线的突出优点是对曲线的局部修改功能,因为
,所以控制多边形的顶点对曲线的控制灵活而直观。
样条曲线的次数可根据需要指定,不像Bezier曲线的次数是由控制点的个数来确定。
阶数k,控制顶点数n+1,节点个数m+1,具有以下关系: m=n+k
记T为:Tn,k={ti}(ti≤ti+1 ,i=0,1,2,…,n,…,n+k)
(5). 3次Bézier曲面的矩阵表达式:Microsoft Visual Studio 6.0
2、在zjie_BView.h文件中声明成员函数和变量:
2.点击绘制三次B样条曲线:
三.绘制Bezier曲线:
1.点击绘制Bezier曲线:
、四次Bezier曲线:
点击绘制曲面:。
(计算机图形学)自由曲线曲面

参数连续性,用C 表示 C0连续(0阶参数连续) —— 指曲线相连,前一段曲线的终点
阶数
t=1与后一段曲线的起点t=0相同,即 相邻两段曲线结合点处有相同坐标。
C1连续(一阶参数连续) ——代表两个相邻曲线段的方程在相交
点处有相同的一阶导数(切线)。 (一阶导数反映了曲线对参数 t 的变 化速度)
B2,3(t)ຫໍສະໝຸດ Ot4个基函数
7.2.2 Bernstein基函数及曲线的性质
Bi ,n (t ) n! i i t i (1 t ) ni C n t (1 t ) ni i!(n i)!
t∈〔0,1〕(i=0,1,2……n) ,t∈〔0,1〕
1.非负性: Bi,n (t ) 0
void CTestView::DrawBezier()//绘制Bezier曲线 { CDC *pDC=GetDC(); CPen NewPen,*pOldPen; NewPen.CreatePen(PS_SOLID,1,RGB(0,0,255));//曲线颜色 pOldPen=pDC->SelectObject(&NewPen); pDC->MoveTo(P[0]); for(double t=0.0;t<=1.0;t+=0.01) { double x=0,y=0; for(int i=0;i<=n;i++) { x+=P[i].x*C(n,i)*pow(t,i)*pow(1-t,n-i); y+=P[i].y*C(n,i)*pow(t,i)*pow(1-t,n-i); } pDC->LineTo(Round(x),Round(y)); } pDC->SelectObject(pOldPen); NewPen.DeleteObject(); ReleaseDC(pDC); }
自由曲线-自由曲面设计

若令 d k x
n
a
j 0
m
k 0
i k
Si ,
d
k 0
n
i yk xk Ti;则可得方程组: k
j
S i j Ti
这里有m+1个方程,可以解出m+1个系数未知数 a0,a1,…am,代入定义即可求出多项式F(x)逼近已知 的n个型值点;
一组实验数据: x 0 10 20 30 40
多项式拟合最小二乘法
设已知型值点为(xi,yi)(i=1,2,…n),现构造一个 m(m<n-1)次多项式函数y=F(x)逼近这些型值点; 逼近的好坏可用各点偏差的加权平方和来衡量:
(a0 , a1 ,..., am ) d k [ F ( xk ) yk ]2
k 0 n
F ( x) a j x j 使得偏 令F(x)为一个m次多项式,
j 0
m
差平方和 达到极小;
最小二乘法解决逼近问题
根据求极值问题的方法可知,使 (a j ) 达到极小的 a j (j=0,1…,m)必须满足下列方程组:
n m i 2 d k a j xkj y k xk 0 ai k 0 j 0
i 0,1,..... m
1972年,德布尔(de Boor)给出了B样条的标准计算 方法;
1974年,通用汽车公司的戈登(Gordon)和里森费尔 德(Riesenfeld)在B样条理论的基础上,提出了B样 条曲线、曲面;
1975年,美国的佛斯普里尔(Versprill)提出了有理B 样条方法; 80年代后期,美国的皮格尔(Piegl)和蒂勒(Tiller)将 有理B样条发展成非均匀有理B样条(NURBS)方法;
计算机图形学Bezeir算法实验报告

实验四 自由曲线绘制算法1. 实验目的:1.掌握曲线的表示形式、曲线的连续性条件、拟合和逼近的基本概念2.掌握Bezier 曲线的性质3.编程实现Bezier 曲线生成算法2. 实验描述:绘制三次Bezier 曲线,可以采用公式法或德卡斯特里奥(De Casteliau )算法绘制。
3. 算法设计:在空间给定1n +个点012,,,,n PP P P ,称下列参数曲线为n 次Bezier 曲线:,0()(),01ni i n i P t P B tt ==≤≤∑其中,()i n B t 是Bernstein 基函数,其表达式为:,!()(1)!()!i n ii n n B t t ti n i -=--,接着我们讨论3次Bezier 曲线,我们也采用将表达式改写为矩阵形式的方法,我们得到:3303!()(1)!(3)!i i ii P t P t t i i -==--∑32230123(1)3(1)3(1)t P t t P t t P t P =-+-+-+01323232323331,363,33,P P t t t t t t t t t P P ⎡⎤⎢⎥⎢⎥⎡⎤=-+-+-+-+⎣⎦⎢⎥⎢⎥⎣⎦01322313313630,,,133001000P P t t t P P --⎡⎤⎡⎤⎢⎥⎢⎥-⎢⎥⎢⎥⎡⎤=⎣⎦⎢⎥⎢⎥-⎢⎥⎢⎥⎣⎦⎣⎦4. 源程序://1)TestView.hclass CTestView : public CView {…….protected:bool Flag;//标志CPoint *pt;//顶点int CtrlPoint;//控制多边形顶点……..}2) //TestView.cpp#include "math.h"//数学头文件#define N_MAX_POINT 10//控制多边形的最大顶点数#define ROUND(a) int(a+0.5) //四舍五入。
计算机图形学Bezeir算法实验报告

实验四 自由曲线绘制算法1.实验目的:1.掌握曲线的表示形式、曲线的连续性条件、拟合和逼近的基本概念2.掌握Bezier 曲线的性质3.编程实现Bezier 曲线生成算法2.实验描述:绘制三次Bezier 曲线,可以采用公式法或德卡斯特里奥(De Casteliau )算法绘制。
3.算法设计:在空间给定1n +个点012,,,,n P PP P ,称下列参数曲线为n 次Bezier 曲线:,0()(),01n i i n i P t PB t t ==≤≤∑其中,()i n B t 是Bernstein 基函数,其表达式为:,!()(1)!()!i n ii n n B t t t i n i -=--,接着我们讨论3次Bezier 曲线,我们也采用将表达式改写为矩阵形式的方法,我们得到:3303!()(1)!(3)!i i ii P t P t t i i -==--∑32230123(1)3(1)3(1)t P t t P t t P t P =-+-+-+01323232323331,363,33,P P t t t t t t t t t P P ⎡⎤⎢⎥⎢⎥⎡⎤=-+-+-+-+⎣⎦⎢⎥⎢⎥⎣⎦01322313313630,,,133001000P P t t t P P --⎡⎤⎡⎤⎢⎥⎢⎥-⎢⎥⎢⎥⎡⎤=⎣⎦⎢⎥⎢⎥-⎢⎥⎢⎥⎣⎦⎣⎦4.源程序://1)TestView.hclass CTestView : public CView {…….protected:bool Flag;//标志CPoint *pt;//顶点int CtrlPoint;//控制多边形顶点……..}2) //TestView.cpp#include "math.h"//数学头文件#define N_MAX_POINT 10//控制多边形的最大顶点数#define ROUND(a) int(a+0.5) //四舍五入。
自由曲线绘制算法

实验四自由曲线绘制算法1.实验目的:掌握曲线的表示形式、曲线的连续性条件、拟合和逼近的基本概念掌握Bezier曲线的性质编程实现Bezier曲线生成算法2.实验描述:绘制三次Bezier曲线,可以采用公式法或德卡斯特里奥(De Casteliau)算法绘制3.算法设计:当n=3时,Bezier曲线的控制多边形有4个控制点P0、P1、P2和P3,Bezier曲线是三次多项式。
P(t)=∑PiBi,n(t),t∈[0,1];三次Bezier曲线是自由曲线。
4.源程序://1)T estView.hclass CTestV iew : public CView{public:void DrawCharPolygon();int Factorial(int m);double Cnk(const int &n, const int &i);void DrawBezier();protected:bool Flag;//标志CPoint *pt;//顶点int CtrlPoint;//控制多边形顶点……..}2) //T estView.cpp#include "math.h"//数学头文件#define N_MAX_POINT 10//控制多边形的最大顶点数#define ROUND(a) int(a+0.5) //四舍五入。
CT estView::CT estView(){Flag=false;}void CT estView::OnMENUBezierCurve(){// TODO: Add your command handler code hereRedrawWindow();AfxGetMainWnd()->SetWindowText("三次Bezier曲线");//显示标题MessageBox("单击左键绘制控制多边形,单击右键绘制曲线","提示",MB_OK);pt=new CPoint[N_MAX_POINT];Flag=true;CtrlPoint=0;}void CT estView::DrawBezier()//绘制Bezier曲线{CClientDC dc(this);double x,y;int rate=800,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 CT estView::Cnk(const int &n, const int &i)//Bernstein第一项{return double(Factorial(n)/(Factorial(i)*Factorial(n-i)));}int CT estView::Factorial(int m)//阶乘函数{int f=1;for(int i=1;i<=m;i++)f*=i;return f;}void CT estView::DrawCharPolygon()//绘制控制多边形{CClientDC dc(this);CPen MyPen,*pOldPen;MyPen.CreatePen(PS_SOLID,3,RGB(0,0,0));//控制多边形pOldPen=dc.SelectObject(&MyPen);for(int i=0;i<CtrlPoint;i++){if(i==0){dc.MoveTo(pt[i]);dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2);}else{dc.LineTo(pt[i]);dc.Ellipse(pt[i].x-2,pt[i].y-2,pt[i].x+2,pt[i].y+2);}}dc.SelectObject(pOldPen);MyPen.DeleteObject();}void CT estView::OnLButtonDown(UINT nFlags, CPoint point)//获得屏幕控制点坐标{// TODO: Add your message handler code here and/or call defaultCView::OnLButtonDown(nFlags, point);if(Flag){pt[CtrlPoint].x=point.x;pt[CtrlPoint].y=point.y;if(CtrlPoint<N_MAX_POINT)CtrlPoint++;elseFlag=false;DrawCharPolygon();}}void CT estView::OnRButtonDown(UINT nFlags, CPoint point)//调用绘制函数{// TODO: Add your message handler code here and/or call defaultFlag=false;DrawBezier();CView::OnRButtonDown(nFlags, point);}5.运行结果:(屏幕截图)。
自由曲线曲面的基本原理(下)

自由曲线曲面的基本原理(下)浙江大学单岩浙江黄岩华日(集团)公司梁建国5 自由曲线的几点说明下面我们针对造型的实际需要,对自由曲线的特点和生成方式作几点补充说明,以便读者更有效地使用CAD/CAM软件中的有关功能5.1 与坐标系无关性读者或许会注意到,在Bezier曲线的表达式中(见上期文章),根本没有出现任何坐标变量(如x,y,z),即使是控制顶点P i的坐标值也未出现,即这种表达式是与坐标无关的。
它的优点至少有三个方面:(1)与现实世界保持一致,更易于理解。
现实世界中本来就不存在什么坐标系,坐标系只是人为创造出来的一个位置基准,是可以任意变化的。
实际空间上的每一个点客观上占据着一个确定的空间位置,是不依赖于任何坐标系的客观存在,而坐标系仅仅是用于帮助描述这个空间位置。
也就是说,对于一个确定的空间点,坐标系的变化不会使其空间位置发生任何变化,但其坐标值(即对这个位置的描述)却发生变化。
同样,一条自由曲线是由一组控制顶点通过插值得到的,其形状仅与控制顶点之间的位置(注意不是坐标值!)和插值方式有关,因此其表达式中自然没有必要出现坐标变量。
(2)表达方便、统一。
对于非参数化表达(如直线y=x)而言,当坐标系逆时针旋转90度时,它的表达式就发生变化(y=0),有时甚至无法得到新的表达式。
这就为编制统一的处理软件带来了极大困难。
而Bezier曲线的表达式与坐标系无关,始终保持统一,因此方便编制统一的计算程序。
(3)图形处理速度更快。
当我们在计算机屏幕上显示一条曲线时,它已按一定精度离散成许多点。
如果这时需要对显示进行一些变换(如旋转),则对于非参数化表达的曲线我们只能将其离散点一一进行变换(因为其表达式发生了变化或者根本无法表达),这将耗费大量的计算时间。
而对于Bezier曲线则只要将数量有限的控制顶点进行变换后重新通过插值运算重新绘出新的曲线即可,而插值过程是线性运算(见上期文章),速度远高于旋转变换运算,因此整个变换过程要比非参数化表达的曲线快得多。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验四 自由曲线曲面算法实验实验项目性质:设计性实验所属课程名称:3D 游戏图形学实验计划学时:3学时一、 实验目的和要求1. 了解自由曲线和曲面的生成原理;2. 掌握并实现Bezier 曲线和B 样条曲线的生成算法;3. 实现Bezier 曲面的生成算法。
二、 实验原理1. Bezier 曲线是通过一组多边形折线的顶点来定义的。
如果折线的顶点固定不变,则由其定义的Bezier 曲线是唯一的。
在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始处和终止处,其他的点用于控制曲线的形状及阶次。
曲线的形状趋向于多边形折线的形状,要修改曲线,只要修改折线的各顶点就可以了。
因此,多边形折线又称Bezier 曲线的控制多边形,其顶点称为控制点。
三次多项式,有四个控制点,如图1所示,其数学表示如下:,300.31 1.32 2.33 3.30()()()()()()i i i Q t PB t P B t PB t P B t P B t ===+++∑32230123(1)3(1)3(1),[0,1]t P t t P t t P t P t =-+-+-+∈(1)其矩阵形式为01322313313630()(1),[0,1]33001000P P Q t t t t t P P --⎡⎤⎡⎤⎢⎥⎢⎥-⎢⎥⎢⎥=∈⎢⎥⎢⎥-⎢⎥⎢⎥⎣⎦⎣⎦(2)2. B 样条曲线保留了Bezier 曲线的优点,对Bezier 曲线进行了拓广,用B 样条基代替Bernstein 基,克服了Bezier 曲线由于整体表示带来的不具备局部性质的缺点。
B 样条曲线的数学定义为0n k k,m k p(t)P B (t)==∑(3)式中,(0,1,,)k P k n = 为n+1个控制点,由控制点顺序连成的折线称为B 样条控制多边形。
m 是一个阶参数,可以取2到控制顶点个数n+1之间的任一整数,m-1是B 样条曲线的次数。
参数t 的选取取决于B 样条结点矢量的选取。
k,m B (t)是B 样条基函数,()()k 1,1,,11,1111 ()0 ()k k k k m k m k m k m k m k k m k t t t B t t t t t B t B t B t t t t t ++-+-+-++≤<⎧=⎨⎩--=+--若其它 (4) k t 是结点值,01(,,,)n m T t t t += 构成了m-1次B 样条函数的结点矢量,其中的结点是非减序列,所生成的B 样条曲线定义在从结点值1m t -到结点值1n t +的区间上,而每个基函数定义在t 的取值范围内的k t 到k+m t 的子区间内。
从式(3)和(4)可以看出,仅仅给定控制点和参数m 还不足以完全表达B 样条曲线,还需要给定结点矢量并使用公式(4)来获得基函数。
对于三次均匀周期性B 样条曲线,m=4,如果用4个控制点来拟合三次曲线,则n=3。
假设结点矢量(0,1,2,3,4,5,6,7)T =,于是得到基函数计算式为:()(),1,,11,11 1()0 ()11k k m k m k m k t k B t t k k m t B t B t B t m m -+-≤<+⎧=⎨⎩-+-=+--其他 (5)最终得到该B 样条曲线的矩阵形式为,0010414243423013223()1331363011303061410 t [0,1)nk k mk ,,,,B B p t P B P P B (t)B (t)B (t)B (t)P P P P t t t P P T M G ==⎡⎤⎢⎥⎢⎥=⋅⎡⎤⎣⎦⎢⎥⎢⎥⎣⎦--⎡⎤⎡⎤⎢⎥⎢⎥-⎢⎥⎢⎥⎡⎤=⋅⋅⋅⎣⎦⎢⎥⎢⎥-⎢⎥⎢⎥⎣⎦⎣⎦=⋅⋅∈∑ (6) 三、 实验内容1.下面的代码用来生成三次Bezier 曲线,将代码补充完整,编译运行;修改代码,利用OpenGL 函数生成三次Bezier 曲线。
参考代码:#include <GL/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 CaleBZPoints(){添加代码;生成Bezier 曲线上的点;}void ControlPoint(vector <Point> vpt){glPointSize(2);for(int 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);CaleBZPoints();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;}2. 改写教材P241程序8-1,实现三次均匀周期性B样条曲线的生成算法,并利用OpenGL函数生成同样的三次周期性B样条曲线。
参考代码:#include <GL/glut.h>#include <math.h>#include <stdlib.h>class Pt3D{public:GLfloat x,y,z;};void GetCnk(GLint n, GLint *c){GLint i,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 GetPointPr( GLint *c, GLfloat t, Pt3D *Pt, int ControlN, Pt3D *ControlP){GLint k,n=ControlN-1;GLfloat Bernstein;Pt->x=0.0; Pt->y=0.0; Pt->z=0.0;for(k=0; k<ControlN; k++){Bernstein=c[k]*pow(t,k)*pow(1-t,n-k);Pt->x += ControlP[k].x*Bernstein;Pt->y += ControlP[k].y*Bernstein;Pt->z += ControlP[k].z*Bernstein;}}void BezierCurve(GLint m, GLint ControlN, Pt3D *ControlP){GLint *C,i;Pt3D CurvePt;C = new GLint[ControlN];GetCnk(ControlN-1, C);glBegin (GL_POINTS);for(i=0;i<m;i++){GetPointPr(C,(GLfloat)i/(GLfloat)m, &CurvePt, ControlN, ControlP);glVertex2f(CurvePt.x, CurvePt.y);}glEnd();delete [] C;}void initial(void){glClearColor (1.0, 1.0, 1.0, 0.0);// pNurb=gluNewNurbsRenderer();}void Display(void){glClear(GL_COLOR_BUFFER_BIT);GLint ControlN=4,m=500;Pt3DControlP[4]={{-80.0,-40.0,0.0},{-10.0,90.0,0.0},{10.0,-90.0,0.0},{80. 0,40.0,0.0}};glColor3f(0.0, 0.0, 0.0);BezierCurve(m,ControlN,ControlP);// gluBeginCurve(pNurb);for(GLint i=0;i<4;i++)glVertex3f(ControlP[i].x,ControlP[i].y,ControlP[i].z);glEnd();glFlush();}void Reshape(GLint newWidth, GLint newHeight){glViewport(0,0,newWidth,newHeight);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluOrtho2D(-100.0,100.0,-100.0,100.0);}void main(void){glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow("Bezier曲线");initial();glutDisplayFunc(Display);glutReshapeFunc(Reshape);glutMainLoop();}3. 利用OpenGL函数实现Bezier曲面的生成算法。