建议阅读资料:
- 课件
学习要求:
- 掌握贝塞尔曲线和曲面的生成算法
Task1. 使用OpenGL画点和画线功能,实现贝塞尔曲线生成算法。
说明:仅能使用OpenGL的画点和画线功能,不能直接调用其贝塞尔曲线生成功能。
- 自行设置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);
}
}
- 在上述基础上,分别增加控制点数为4、5、6、7、8,并生成相应的曲线形成动画。
完成,见如下截图和上一题程序或者工程Bezier Curves_animation。
/* 注:
绿色线是最终画出来的效果,粉色线代表的是每一层的的点的位置的变化,展示贝塞尔曲线的生成过程, 深蓝紫色线是最外层的我们输入的控制点的连线)
粉色线代表老师提供的视频的这每一层点(黄色框框出)的变化曲线
4个控制点
5个控制点
- 自行完善功能,例如提供控制点的选取或移动功能;
完成,可以实现点击”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的画点、画线和画面功能,不能直接调用其贝塞尔曲线生成功能。
- 自行设置3*3个控制点,利用de Casteljau生成贝塞尔曲面。要求生成曲面形成过程的动画。
完成,见如下截图和运行视频”贝塞尔曲面生成过程动画”或者工程Bezier Surfaces_animation。
2*2
- 在上述基础上,分别增加控制点数为4*4、5*5并生成相应的曲面形成动画。
完成,见如下截图和运行视频”贝塞尔曲面生成过程动画2”或者工程Bezier Surfaces_animation。
。
生成动画:
- 自行完善功能,例如提供控制点的选取或移动功能;改善生成图形美观程度。
完成,见如下截图或者工程Bezier Surfaces或者程序运行视频的”移动贝塞尔曲面”
可以实现点击”z”选取下一个点
wasdqe使点上下左右里外移动