预览加载中,请您耐心等待几秒...
1/10
2/10
3/10
4/10
5/10
6/10
7/10
8/10
9/10
10/10

在线预览结束,喜欢就下载吧,查找使用更方便

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

贝塞尔曲面 这篇教程旨在介绍贝塞尔曲面,希望有比我更懂艺术的人能用她作出一些很COOL的东东并 且展示给大家。教程不能用做一个完整的贝塞尔曲面库,而是一个展示概念的程序让你熟悉 曲面怎样实现的。而且这不是一篇正规的文章,为了方便理解,我也许在有些地方术语不当; 我希望大家能适应这个。最后,对那些已经熟悉贝塞尔曲面想看我写的如何的,真是丢脸; -)但你要是找到任何纰漏让我或者NeHe知道,毕竟人无完人嘛?还有,所有代码没有象我 一般写程序那样做优化,这是故意的。我想每个人都能明白写的是什么。好,我想介绍到此 为止,继续看下文! 数学::恶魔之音::(警告:内容有点长~) 好,如果想理解贝塞尔曲面没有对其数学基本的认识是很难的,如果你不愿意读这一部分或 者你已经知道了关于她的数学知识你可以跳过。首先我会描述贝塞尔曲线再介绍生成贝塞尔 曲面。 奇怪的是,如果你用过一个图形程序,你就已经熟悉了贝塞尔曲线,也许你接触的是另外的 名称。它们是画曲线的最基本的方法,而且通常被表示成一系列点,其中有两个点与两端点 表示左右两端的切线。下图展示了一个例子。 这是最基础的贝塞尔曲线(长点的由很多点在一起(多到你都没发现))。这个曲线由4 个点定义,有2个端点和2个中间控制点。对计算机而言这些点都是一样的,但是特意的我 们通常把前后两对点分别连接,因为他们的连线与短点相切。曲线是一个参数化曲线,画的 时候从曲线上平均找几点连接。这样你可以控制曲线曲面的精度(和计算量)。最通常的方 法是远距离少细分近距离多细分,对视点,看上去总是很完好的曲面而对速度的影响总是最 小。 贝塞尔曲面基于一个基本方程,其他复杂的都是基于此。方程为: t+(1-t)=1 看起来很简单不是?的确是的,这是最基本的贝塞尔曲线,一个一维的曲线。你也许从术语 中猜到,贝塞尔曲线是多项式形式的。从线性代数知,一个一维的多项式是一条直线,没多 大意思。好,因为基本方程对所有t都成立,我们可以平方,立方两边,怎么都行,等式都 是成立的,对吧?好,我们试试立方。 (t+(1-t))^3=1^3 t^3+3*t^2*(1-t)+3*t*(1-t)^2+(1-t)^3=1 这是我们最常用的计算贝塞尔曲面的方程,a)她是最低维的不需要在一个平面内的多项式 (有4个控制点),而且b)两边的切线互相没有联系(对于2维的只有3个控制点)。那 么你看到了贝塞尔曲线了吗?呵呵,我们都没有,因为我还要加一个东西。 好,因为方程左边等于1,可以肯定如果你把所有项加起来还是等于1。这是否意味着在计 算曲线上一点时可以以此决定该用每个控制点的多少呢?(答案是肯定的)你对了!当我们 要计算曲线上一点的值我们只需要用控制点(表示为向量)乘以每部分再加起来。基本上我 们要用0<=t<=1,但不是必要的。不明白了把?这里有函数: P1*t^3+P2*3*t^2*(1-t)+P3*3*t*(1-t)^2+P4*(1-t)^3=Pnew 因为多项式是连续的,有一个很好的办法在4个点间插值。曲线仅经过P1,P4,分别当t=1,0。 好,一切都很好,但现在我怎么把这个用在3D里呢?其实很简单,为了做一个贝塞尔曲面, 你需要16个控制点,(4*4),和2个变量t,v。你要做的是计算在分量v的沿4条平行曲 线的点,再用这4个点计算在分量t的点。计算了足够的这些点,我们可以用三角带连接他 们,画出贝塞尔曲面。 恩,我认为现在已经有足够的数学背景了,看代码把! #include<math.h>//数学库 #include<stdio.h>//标准输入输出库 #include<stdlib.h>//标准库 typedefstructpoint_3d{//3D点的结构 doublex,y,z; }POINT_3D; typedefstructbpatch{//贝塞尔面片结构 POINT_3Danchors[4][4];//由4x4网格组成 GLuintdlBPatch;//绘制面片的显示列表名称 GLuinttexture;//面片的纹理 }BEZIER_PATCH; BEZIER_PATCHmybezier;//创建一个贝塞尔曲面结构 BOOLshowCPoints=TRUE;//是否显示控制点 intdivs=7;//细分精度,控制曲面的显示精度 以下是一些简单的向量数学的函数。如果你是C++爱好者你可以用一个顶点类(保证其为 3D的)。 //两个向量相加,p=p+q POINT_3DpointAdd(POINT_3Dp,POINT_3Dq){ p.x+=q.x;p.y+=q.y;p.z+=q.z; returnp; } //向量和标量相乘p=c*p POINT_3DpointTi