双三次 Bezier 曲面

双三次 Bezier 曲面的定义

Bezier 曲面是由 Bezier 曲线扩展得到,它是两组正交的 Bezier 曲线控制点构造空间网格生成的曲面

p ( u , v ) = ∑ i = 0 3 ∑ j = 0 3 P i , j B i , 3 ( u ) B j , 3 ( v ) , ( u , v ) ∈ [ 0 , 1 ] × [ 0 , 1 ] \begin{equation} \bm{p}(u, v) = \sum_{i=0}^{3}\sum_{j=0}^{3} P_{i,j}B_{i, 3}(u)B_{j,3}(v), (u, v) \in [0, 1] \times [0, 1] \end{equation} p(u,v)=i=03j=03Pi,jBi,3(u)Bj,3(v),(u,v)[0,1]×[0,1]

其中, P i j P_{ij} Pij 是 16 个控制点, B i , 3 ( u ) B_{i, 3}(u) Bi,3(u) B j , 3 ( v ) B_{j, 3}(v) Bj,3(v) 是 Bernstein 基函数。

在这里插入图片描述

对 (1) 式展开,有
p ( u , v ) = [ B 0 , 3 ( u ) B 1 , 3 ( u ) B 2 , 3 ( u ) B 3 , 3 ( u ) ] [ P 0 , 0 P 0 , 1 P 0 , 2 P 0 , 3 P 1 , 0 P 1 , 1 P 1 , 2 P 1 , 3 P 2 , 0 P 2 , 1 P 2 , 2 P 2 , 3 P 3 , 0 P 3 , 1 P 3 , 2 P 3 , 3 ] [ B 0 , 3 ( v ) B 1 , 3 ( v ) B 2 , 3 ( v ) B 3 , 3 ( v ) ] \begin{equation} \bm{p}(u, v) = \begin{bmatrix} B_{0, 3}(u) & B_{1, 3}(u) & B_{2, 3}(u) & B_{3, 3}(u) \end{bmatrix} \begin{bmatrix} P_{0, 0} & P_{0, 1} & P_{0, 2} & P_{0, 3} \\ P_{1, 0} & P_{1, 1} & P_{1, 2} & P_{1, 3} \\ P_{2, 0} & P_{2, 1} & P_{2, 2} & P_{2, 3} \\ P_{3, 0} & P_{3, 1} & P_{3, 2} & P_{3, 3} \\ \end{bmatrix} \begin{bmatrix} B_{0, 3}(v) \\ B_{1, 3}(v) \\ B_{2, 3}(v) \\ B_{3, 3}(v) \end{bmatrix} \end{equation} p(u,v)=[B0,3(u)B1,3(u)B2,3(u)B3,3(u)] P0,0P1,0P2,0P3,0P0,1P1,1P2,1P3,1P0,2P1,2P2,2P3,2P0,3P1,3P2,3P3,3 B0,3(v)B1,3(v)B2,3(v)B3,3(v)

B 0 , 3 ( u ) , B 1 , 3 ( u ) , B 2 , 3 ( u ) , B 3 , 3 ( u ) , B 0 , 3 ( v ) , B 1 , 3 ( v ) , B 2 , 3 ( v ) , B 3 , 3 ( v ) B_{0, 3}(u),B_{1, 3}(u),B_{2, 3}(u),B_{3, 3}(u), B_{0, 3}(v), B_{1, 3}(v), B_{2, 3}(v), B_{3, 3}(v) B0,3(u)B1,3(u)B2,3(u)B3,3(u)B0,3(v)B1,3(v)B2,3(v)B3,3(v)是三次 Bernstein 基函数,

{ B 0 , 3 ( u ) = − u 3 + 3 u 2 − 3 u + 1 B 1 , 3 ( u ) = 3 u 2 − 6 u 2 + 3 u B 2 , 3 ( u ) = − 3 u 3 + 3 u 2 B 3 , 3 ( u ) = u 3 \begin{equation} \begin{cases} B_{0, 3}(u) = -u^3 + 3u^2 -3u +1 \\ B_{1, 3}(u) = 3u^2 -6u^2+3u \\ B_{2, 3}(u) = -3u^3 + 3u^2 \\ B_{3, 3}(u) = u^3 \end{cases} \end{equation} B0,3(u)=u3+3u23u+1B1,3(u)=3u26u2+3uB2,3(u)=3u3+3u2B3,3(u)=u3
{ B 0 , 3 ( v ) = − v 3 + 3 v 2 − 3 v + 1 B 1 , 3 ( v ) = 3 v 2 − 6 v 2 + 3 v B 2 , 3 ( v ) = − 3 v 3 + 3 v 2 B 3 , 3 ( v ) = v 3 \begin{equation} \begin{cases} B_{0, 3}(v) = -v^3 + 3v^2 -3v +1 \\ B_{1, 3}(v) = 3v^2 -6v^2+3v \\ B_{2, 3}(v) = -3v^3 + 3v^2 \\ B_{3, 3}(v) = v^3 \end{cases} \end{equation} B0,3(v)=v3+3v23v+1B1,3(v)=3v26v2+3vB2,3(v)=3v3+3v2B3,3(v)=v3

p ( u , v ) = [ u 3 u 2 u 1 ] [ − 1 3 − 3 1 3 − 6 3 0 − 3 3 0 0 1 0 0 0 ] [ P 0 , 0 P 0 , 1 P 0 , 2 P 0 , 3 P 1 , 0 P 1 , 1 P 1 , 2 P 1 , 3 P 2 , 0 P 2 , 1 P 2 , 2 P 2 , 3 P 3 , 0 P 3 , 1 P 3 , 2 P 3 , 3 ] [ − 1 3 − 3 1 3 − 6 3 0 − 3 3 0 0 1 0 0 0 ] [ v 3 v 2 v 1 ] \begin{equation} p(u, v) = \begin{bmatrix} u^3 & u^2 & u & 1 \end{bmatrix} \begin{bmatrix} -1 & 3 & -3 & 1 \\ 3 & -6 & 3 & 0 \\ -3 & 3 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ \end{bmatrix} \begin{bmatrix} P_{0, 0} & P_{0, 1} & P_{0, 2} & P_{0, 3} \\ P_{1, 0} & P_{1, 1} & P_{1, 2} & P_{1, 3} \\ P_{2, 0} & P_{2, 1} & P_{2, 2} & P_{2, 3} \\ P_{3, 0} & P_{3, 1} & P_{3, 2} & P_{3, 3} \\ \end{bmatrix} \begin{bmatrix} -1 & 3 & -3 & 1 \\ 3 & -6 & 3 & 0 \\ -3 & 3 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ \end{bmatrix} \begin{bmatrix} v^3 \\ v^2 \\ v \\ 1 \end{bmatrix} \end{equation} p(u,v)=[u3u2u1] 1331363033001000 P0,0P1,0P2,0P3,0P0,1P1,1P2,1P3,1P0,2P1,2P2,2P3,2P0,3P1,3P2,3P3,3 1331363033001000 v3v2v1

U = [ u 3 u 2 u 1 ] , V = [ v 3 v 2 v 1 ] \bm{U} = \begin{bmatrix} u^3 & u^2 & u & 1 \end{bmatrix} , \bm{V} = \begin{bmatrix} v^3 & v^2 & v & 1 \end{bmatrix} U=[u3u2u1],V=[v3v2v1]

M = [ − 1 3 − 3 1 3 − 6 3 0 − 3 3 0 0 1 0 0 0 ] , P = [ P 0 , 0 P 0 , 1 P 0 , 2 P 0 , 3 P 1 , 0 P 1 , 1 P 1 , 2 P 1 , 3 P 2 , 0 P 2 , 1 P 2 , 2 P 2 , 3 P 3 , 0 P 3 , 1 P 3 , 2 P 3 , 3 ] \bm{M} = \begin{bmatrix} -1 & 3 & -3 & 1 \\ 3 & -6 & 3 & 0 \\ -3 & 3 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ \end{bmatrix} , \bm{P} = \begin{bmatrix} P_{0, 0} & P_{0, 1} & P_{0, 2} & P_{0, 3} \\ P_{1, 0} & P_{1, 1} & P_{1, 2} & P_{1, 3} \\ P_{2, 0} & P_{2, 1} & P_{2, 2} & P_{2, 3} \\ P_{3, 0} & P_{3, 1} & P_{3, 2} & P_{3, 3} \\ \end{bmatrix} M= 1331363033001000 ,P= P0,0P1,0P2,0P3,0P0,1P1,1P2,1P3,1P0,2P1,2P2,2P3,2P0,3P1,3P2,3P3,3

p ( u , v ) = U M P M T V T \begin{equation} \bm{p}(u, v) = \bm{U}\bm{M}\bm{P}\bm{M}^{T}\bm{V}^{T} \end{equation} p(u,v)=UMPMTVT

M \bm{M} M 是对称矩阵,即 M T = M M^T = M MT=M.

生成曲面时,可以先固定 u 变化 v 得到一簇 Bezier 曲线,然后固定 v,变化 u 得到另一簇 Bezier 曲线,两卒曲线交织生成双三次 Bezier 曲面。

这里的程序算法的示意说明

// 读取控制点

void ReadControlPoint(Point3 P[4][4]) {

	double M[4][4];
	M[0][0] = -1;M[0][1] =  3;M[0][2] = -3;M[0][3] = 1;
	M[1][0] =  3;M[1][1] = -6;M[1][2] =  3;M[1][3] = 0;
	M[2][0] = -3;M[2][1] =  3;M[2][2] =  0;M[2][3] = 0;
	M[3][0] =  1;M[3][1] =  0;M[3][2] =  0;M[3][3] = 0;
	
	Point3 mControlPoint[4][4];
	for (int i=0; i<4; i++) {
		for (int j=0; j<4; j++) {
			mControlPoint[i][j] = P[i][j]	
		}
	}
	// 数字矩阵左乘 三维点矩阵 M * mControlPoint
	// 计算转置矩阵 M^T
	// 数字矩阵右乘 三维点矩阵 mControlPoint * M

	double setp = 0.1;
	double u3, u2, u1, u0, v3, v2, v1, v0;
	// 定义 Point Pt;
	for (double u=0; u<=1; u+=step) {
		for (double v=0; v<=1; v+=step) {
			u3 = u*u*u; v3 = v*v*v;
			u2 = u*u; v2 = v*v;
			u1 = u;	v1 = v;
			u0 = 1; v0 = 1;
			Pt = ....
			// 根据公式计算出 pt
			// 斜二投影
			//if (v == 0) 特殊处理
			// 绘制点
			
		}
	}
	for (double v=0; v<=1; v+=step) {
		for (double u=0; u<=1; u+=step) {
			u3 = u*u*u; v3 = v*v*v;
			u2 = u*u; v2 = v*v;
			u1 = u;	v1 = v;
			u0 = 1; v0 = 1;
			Pt = ....
			// 根据公式计算出 pt
			// 斜二投影
			
			//if (u == 0) 特殊处理
			// 绘制点
			
		}
	}

	
}

// 计算斜二投影

Point2 ObliqueProjection(Point3 P3) {
	Ponit2 P2;
	P2.x = P3.x - P3.z * sqrt(2.0) / 2.0;
	P2.y = P3.y - P3.z * sqrt(2.0) / 2.0;
	return P2;
}

参考 《计算几何算法与实现》孔令德

  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要绘制三次Bezier曲面,可以使用OpenGL中的glMap2f和glEvalMesh2函数。首先,需要使用glMap2f函数来设置控制点(CP)和曲面的参数范围。使用glMap2f函数可以将CP映射到二维参数空间,这个过程类似于将一个函数的自变量映射到函数图像上。 接下来,使用glEvalMesh2函数来计算曲面上的顶点。glEvalMesh2函数会自动计算曲面上的点,并将它们存储在顶点缓冲区中,可以使用OpenGL的其他函数来绘制这些点。 下面是一段OpenGL代码,可以绘制一个简单的三次Bezier曲面: ```C++ // 设置控制点和参数范围 GLfloat ctrlpoints[4][4][3] = { {{-1.5, -1.5, 0.0}, {-0.5, -1.5, 1.0}, {0.5, -1.5, -1.0}, {1.5, -1.5, 0.0}}, {{-1.5, -0.5, 1.0}, {-0.5, -0.5, 3.0}, {0.5, -0.5, -3.0}, {1.5, -0.5, 1.0}}, {{-1.5, 0.5, -1.0}, {-0.5, 0.5, -3.0}, {0.5, 0.5, 3.0}, {1.5, 0.5, -1.0}}, {{-1.5, 1.5, 0.0}, {-0.5, 1.5, 1.0}, {0.5, 1.5, -1.0}, {1.5, 1.5, 0.0}} }; glMap2f(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4, &ctrlpoints[0][0][0]); // 开启自动计算曲面上的顶点 glEnable(GL_MAP2_VERTEX_3); glEnable(GL_AUTO_NORMAL); // 绘制曲面 glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0); glEvalMesh2(GL_FILL, 0, 20, 0, 20); ``` 在这个例子中,我们使用了一个4x4的控制点矩阵。glMap2f函数将这些控制点映射到二维参数空间,并设置参数范围。glEnable函数开启了自动计算曲面上的顶点和法向量。glMapGrid2f函数设置了绘制曲面的网格,glEvalMesh2函数计算并绘制曲面上的顶点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值