计算机图形学:Bezier曲线的绘制

1.实验目的
掌握Bezier曲线的定义原理及绘制过程

定义:
贝塞尔曲线(Bezier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。

2. 实验要求:
利用OpenGL实现一个三次Bezier曲线,任意输入四个控制点,绘制出对应的贝塞尔曲线;并通过鼠标调整控制点(随机变化或沿某种图案变化)让曲线动态显示。

3.实验代码(部分)
需要先安装glut库

#include<GL/glut.h>
#include<GL/GL.h>
#include<math.h>
void mouseClick(int button, int state, int x, int y)
{
    
    
	if (button == GLUT_LEFT_BUTTON)  
	{
    
    
		if (state == GLUT_DOWN) {
    
    
			if (mask == -1) {
    
    
				for (int i = 0; i < 4; i++)
				{
    
    
					float mouse_x = (x - 200) / 200.0f, mouse_y = (200 - y) / 200.0f;
					float dis = sqrt((mouse_x - ctrl_points[i][0]) * (mouse_x - ctrl_points[i][0]) + (mouse_y - ctrl_points[i][1]) * (mouse_y - ctrl_points[i][1]));
					if (dis < 0.1f) mask = i;
				}

			}

		}
		else if (state == GLUT_UP)
			mask = -1;
	}
}

deCateljau算法:
在C++中,Bezier曲线常使用deCateljau算法生成,其思想就是每一次都遍历相邻的控制点,根据给定参数t在两相邻控制点形成的线段上取一个新的控制点。这样,每遍历一遍之前的控制点后生成的新控制点会更加逼近Bezier曲线,且控制点的数量减1,当最后只剩一个控制点时,可以将这个控制点视为Bezier曲线上的点。

void de_Cateljau(int n, GLfloat list[][2])
{
    
    
	float R_x[4];
	float R_y[4];

	int k = 0;
	for (double t = 0.0; t <= 1; t += 0.1)
	{
    
    
		for (int i = 0; i < n; i++) {
    
    
			R_x[i] = ctrl_points[i][0];
			R_y[i] = ctrl_points[i][1];

		}
		
		for (int i = 1; i < n; i++)
		{
    
    
			for (int j = 0; j < n - i; j++)
			{
    
    
				R_x[j] = (1 - t) * R_x[j] + t * R_x[j + 1];
				R_y[j] = (1 - t) * R_y[j] + t * R_y[j + 1];
			}
			
		}
		list[k][0] = R_x[0];
		list[k][1] = R_y[0];
		k++;
	}
}

绘制函数:

void display() {
    
    
	glClearColor(1.0, 1.0, 1.0, 1.0);//(R,G,B,alpha)自己设置
	glClear(GL_COLOR_BUFFER_BIT);//当前可写的颜色缓冲

	glPointSize(3);  
	glColor3f(0.530.510.78);
	for (int i = 0; i < 4; i++) {
    
    
		glBegin(GL_POINTS);//把每个顶点作为一个点进行处理,顶点n定义了点n,绘制N个点。
		glVertex2fv(&ctrl_points[i][0]);
		glEnd();

	}

	glColor3f(0.530.510.78);
	glBegin(GL_LINE_STRIP);//绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,绘制n-1条线段
	for (int i = 0; i < 4; i++) {
    
    
		glVertex2fv(&ctrl_points[i][0]);

	}
	glEnd();

	GLfloat pos_list[11][2] = {
    
     0 };
	de_Cateljau(4, pos_list);

	glColor3f(1.0, 1.0, 0.0);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < 11; i++) {
    
    
		glVertex2fv(pos_list[i]);//指定顶点

	}
	glEnd();
	glFlush();//强制刷新缓冲,保证绘图命令将被执行

}

4.结果样例图
在这里插入图片描述
可以拖动任意点改变bezier曲线的形状。完整源码点这里获取。

猜你喜欢

转载自blog.csdn.net/weixin_52049271/article/details/127936088