计算机图形学--实验7、Bézier Curve贝塞尔曲线

建议阅读资料:

  1. 课件

学习要求:

  1. 掌握贝塞尔曲线和曲面的生成算法

Task1. 使用OpenGL画点和画线功能,实现贝塞尔曲线生成算法。

说明:仅能使用OpenGL的画点和画线功能,不能直接调用其贝塞尔曲线生成功能。

  1. 自行设置3个控制点,利用de Casteljau生成贝塞尔曲线。要求生成曲线形成过程的动画。

完成,见如下截图程序或者工程Bezier Curves_animation

Point Bezierpoint(float t, int m, int num = 0)//返回最终贝塞尔曲线所在的坐标点
{
	k = 1;
	
	if (m != n)
	{
		if (m == 0)glColor3f(197.0 / 256, 139.0 / 256, 247 / 256.0);
		else if (m == 1) glColor3f(134.0 / 256, 114.0 / 256, 237 / 256.0);
		else if (m == 3) glColor3f(216.0 / 256, 136.0 / 256, 224 / 256.0);
		else if (m == 2) glColor3f(247.0 / 256, 138.0 / 256, 189 / 256.0);
		else if (m == 4)  glColor3f(237.0 / 256, 140 / 256.0, 133.0 / 256);
		else if (m == 5) glColor3f(143.0 / 256, 183 / 256.0, 248.0 / 256);
		else if (m == 6)glColor3f(143.0 / 256, 165 / 256.0, 257.0 / 256);
		else if (m == 7) glColor3f(173.0 / 256, 169 / 256.0, 227.0 / 256);
		else if (m == 8) glColor3f(247.0 / 256, 138.0 / 256, 169 / 256.0);
	}
	if (m == n) glColor3f(0.0, 1.0, 0.0);

	while (k <= m)
	{
		for (int i = 0; i <= n - k; i++)
		{
			ctrlpoints[k][i].x = (1 - t)*ctrlpoints[k - 1][i].x + t * ctrlpoints[k - 1][i + 1].x;
			ctrlpoints[k][i].y = (1 - t)*ctrlpoints[k - 1][i].y + t * ctrlpoints[k - 1][i + 1].y;

		}
		k++;
	}
	return ctrlpoints[m][num];
}

void Drawline()//画各层的线
{	glColor3f(1.0, 1.0, 1.0);
	glPointSize(2.0);
	for (T = 0; T <= 1; T = T + 0.0001)
	{

		glBegin(GL_POINTS);
		glColor3f(0.0, 1.0, 0.0);
		glVertex2f(Bezierpoint(T, n).x, Bezierpoint(T, n).y);

		k = n - 1;
		glBegin(GL_POINTS);
		glColor3f(1.0, 1.0, 1.0);

		for (int j = 1; j < n; j++)
		{

			for (int m = 0; m < n; m++)
			{

				glVertex2f(Bezierpoint(T, j, m).x, Bezierpoint(T, j, m).y);
			}
		}

		glEnd();
		glFlush(); 
		glutPostRedisplay();
		Sleep(0.3);
	}
}
  1. 在上述基础上,分别增加控制点数为4、5、6、7、8,并生成相应的曲线形成动画。

完成,见如下截图和上一题程序或者工程Bezier Curves_animation

/* 注:

绿色线是最终画出来的效果,粉色线代表的是每一层的的点的位置的变化,展示贝塞尔曲线的生成过程, 深蓝紫色线是最外层的我们输入的控制点的连线)

粉色线代表老师提供的视频的这每一层点(黄色框框出)的变化曲线

4个控制点

 

5个控制点

 

 

  1. 自行完善功能,例如提供控制点的选取或移动功能;

完成,可以实现点击z选取下一个点  x选取上一个点

  • 鼠标拖拽使点移动
  • wasd使点上下左右移动

见如下截图程序或者工程Bezier Curves_dragpoints或者程序运行视频的拖拽贝塞尔曲线

 

void myKeyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
	case'z'://选定下一个点
		Redmark((t + 1) % (n + 1));
		t = t + 1;
		index = t;
		break;
	case'x'://选定上一个点
		Redmark((t - 1) % (n + 1));
		t = t - 1;
		index = t;
		break;
	case'w'://向上移动
		ctrlpoints[0][t % (n + 1)].y += 0.1;
		Drawline();
		glutPostRedisplay();
		break;
	case's'://向下移动
		ctrlpoints[0][t % (n + 1)].y -= 0.1;
		Drawline();
		glutPostRedisplay();
		break;
	case'a'://向左移动
		ctrlpoints[0][t % (n + 1)].x -= 0.1;
		Drawline();
		glutPostRedisplay();
		break;
	case'd'://向右移动
		ctrlpoints[0][t % (n + 1)].x += 0.1;
		Drawline();
		glutPostRedisplay();
		break;
	default:
		break;
	}
}
int mouse_kind = -1;
int hit_pos_x, hit_pos_y;
int move_x, move_y;
void Drawnew(int x, int y)
{
	y = wh - y;
	ctrlpoints[0][index % (n + 1)].x = x;
	ctrlpoints[0][index % (n + 1)].y = y;
	Drawline();
	glutPostRedisplay();
}
void mouse_hit(int button, int state, int x, int y)
{
	mouse_kind = button;
	switch (button)
	{
	case GLUT_LEFT_BUTTON:
		if (state == GLUT_DOWN)
		{
			ctrlpoints[0][index % (n + 1)].x = float(x - 491) / 100;//调整到接近点的位置
			ctrlpoints[0][index % (n + 1)].y = 1.0 - float(y - 352) / 100;
			Drawline();
			glutPostRedisplay();
		}
		break;
	default:
		break;
	}
}
void mouse_move(int x, int y)
{
	mouse_kind = 3;
	ctrlpoints[0][index % (n + 1)].x = float(x - 491) / 100;
	ctrlpoints[0][index % (n + 1)].y = 1.0 - float(y - 352) / 100;
	Drawline();
	glutPostRedisplay();

}

Task2. 使用OpenGL画点、画线和画面功能,实现贝塞尔曲线生成算法。

说明:仅能使用OpenGL的画点、画线和画面功能,不能直接调用其贝塞尔曲线生成功能。

  1. 自行设置3*3个控制点,利用de Casteljau生成贝塞尔曲面。要求生成曲面形成过程的动画。

完成,见如下截图和运行视频贝塞尔曲面生成过程动画或者工程Bezier Surfaces_animation

2*2

 

  1. 在上述基础上,分别增加控制点数为4*4、5*5并生成相应的曲面形成动画。

完成,见如下截图和运行视频贝塞尔曲面生成过程动画2或者工程Bezier Surfaces_animation

生成动画:

 

  1. 自行完善功能,例如提供控制点的选取或移动功能;改善生成图形美观程度。

完成,见如下截图或者工程Bezier Surfaces或者程序运行视频的移动贝塞尔曲面

可以实现点击z选取下一个点

wasdqe使点上下左右里外移动

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值