利用de Casteljau算法绘制Bezier曲线

之前直接用基计算的Bezier曲线,现在用de Casteljau再次对其进行实现,其主要原因是目前本人对递归的理解非常的不深。。然后之后在CAGD中又要用到大量的递归算法,那么还是从最简单的开始

。。。搞了三个多小时。。终于搞定了,先上代码!

#include<GL/GLUT.H>  
#include <windows.h>      
#include <math.h>      
#include <gl/GL.h>      


GLfloat ctrlPoints[4][2] =
{
		{ -0.8f, 0.1f }, {-0.4f, 0.6f }, { 0.2f, 0.8f }, { 0.7f, 0.2f }
};


void myDisplay(void){
	glClear(GL_COLOR_BUFFER_BIT);

	glPointSize(3);
	glColor3f(1.0, 0.0, 0.0);

	for (int i = 0; i < 4; i++){
		glBegin(GL_POINTS);
			glVertex2fv(&ctrlPoints[i][0]);
		glEnd();
	}


	glColor3f(0.0, 0.0, 1.0);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < 4; i++){
		glVertex2fv(&ctrlPoints[i][0]);
	}
	glEnd();


	float xarray[11];
	float yarray[11];
    int n = 4;//number
	GLfloat ps[11][2];

	int u = 0;
	for(double t = 0.0;t<=1;t+=0.1)
	{ 
		for (int i = 1; i < n; ++i)
		{
			for (int j = 0; j < n - i; ++j)
			{
				if (i == 1) // i==1时,第一次迭代,由已知控制点计算  
				{
					xarray[j] = ctrlPoints[j][0] * (1 - t) + ctrlPoints[j+1][0] * t;
					yarray[j] = ctrlPoints[j][1] * (1 - t) + ctrlPoints[j + 1][1] * t;
					continue;
				}
				// i != 1时,通过上一次迭代的结果计算  
				xarray[j] = xarray[j] * (1 - t) + xarray[j + 1] * t;
				yarray[j] = yarray[j] * (1 - t) + yarray[j + 1] * t;
			}

		}
		ps[u][0] = xarray[0];
		ps[u][1] = yarray[0];
		u++;
	}


	glColor3f(1.0, 1.0, 0.0);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < 11; i++)
	{
		glVertex2fv(ps[i]);
	}
	glEnd();


	glFlush();
}


int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(400, 400);
	glutCreateWindow("opengl1");
	glutDisplayFunc(&myDisplay);
	glutMainLoop();
	return 0;
}
效果当然是帮帮哒,突然发现这样做有个非常明显的好处,就是不用计算Bezier曲线的基,直接套用递归法则就可以用
其最重要的一段是

int n = 4;//number
float xarray[4];
float yarray[4];
GLfloat ps[11][2];


<pre name="code" class="cpp">	int u = 0;
	for(double t = 0.0;t<=1;t+=0.1)
	{ 
		for (int i = 1; i < n; ++i)
		{
			for (int j = 0; j < n - i; ++j)
			{
				if (i == 1) // i==1时,第一次迭代,由已知控制点计算  
				{
					xarray[j] = ctrlPoints[j][0] * (1 - t) + ctrlPoints[j+1][0] * t;
					yarray[j] = ctrlPoints[j][1] * (1 - t) + ctrlPoints[j + 1][1] * t;
					continue;
				}
				// i != 1时,通过上一次迭代的结果计算  
				xarray[j] = xarray[j] * (1 - t) + xarray[j + 1] * t;
				yarray[j] = yarray[j] * (1 - t) + yarray[j + 1] * t;
			}

		}
		ps[u][0] = xarray[0];
		ps[u][1] = yarray[0];
		u++;
	}
 充分体现了递归的算法 
 
如果是几次Bezier曲线,只需要把相对应的n的数以及xarray[]中的改成几就好了

早知道早学递归了。。。

http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html

这篇文章介绍的特别详细

</pre><pre name="code" class="cpp">Input: array P[0:n] of n+1 points and real number u in [0,1] 
Output: point on curve, C(u) 
Working: point array Q[0:n] 
for i := 0 to n do
Q[i] := P[i]; // save input
for k := 1 to n do
for i := 0 to n - k do
Q[i] := (1 - u)Q[i] + u Q[i + 1];
return Q[0];

 这是伪代码。最后贴上效果 
 

利用de Casteljau算法绘制Bezier曲线_第1张图片
感觉自己萌萌哒,感觉自己萌萌哒,感觉自己萌萌哒,那相应的利用de Casteljau算法绘制Bezier曲面和三角曲面指日可待,哦也!




你可能感兴趣的:(递归,OpenGL,CAGD)