1、题目:根据以下Bezier控制顶点,取△t=0.01,按照线性计算方法,编制程序计算曲线上的点,并绘制出曲线和控制多边形。要求打印程序、图。
34.4507 64.8979 92.7423
53.2133 62.9103 78.7443
72.6174 58.5389 64.6679
90.4922 53.8726 51.7908
107.6262 50.2527 40.0300
124.3115 48.5382 29.7099
2、首先贴一个帖子来讲述一下贝塞尔三次拟合的原理,http://www.cnblogs.com/caster99/p/4743637.html
3、然后我们按老方法将数据点保存在一个名为“2.txt”的文档中,开始码代码。
#define _CRT_SECURE_NO_DEPRECATE //防止容器越界报错
#include<iostream>
#include<vector>
#include <GL/glut.h> //使用OPENGL;
#include<iomanip>
using namespace std;
struct point
{
GLfloat x, y, z;
};
GLint winWidth = 600, winHeight = 600; //定义窗口大小
GLfloat x0 = 0.0, b0 = 0.0, z0 = 100.0;
GLfloat xref = 0.0, yref = 0.0, zref = 0.0; // Look-at point.视点
GLfloat Vx = 0.0, Vy = 1.0, Vz = 0.0; // View-up vector
GLfloat xwMin = 0.0, ywMin = 0.0, xwMax = 150.0, ywMax = 150.0;
GLfloat dnear = 0.0, dfar = 100.0;
vector<point>P; //直接定义为全局参数,免去传参的麻烦(其实是本人不会传参hhh)
vector<point>Q;
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0); //Set display window to white 视窗背景颜色
glMatrixMode(GL_MODELVIEW); //Set projectio parameters 项目参数
gluLookAt(x0, b0, z0, xref, yref, zref, Vx, Vy, Vz);
glMatrixMode(GL_PROJECTION); //设置投影变换
glOrtho(xwMin, xwMax, ywMin, ywMax, dnear, dfar);
}
void show()
{
glClear(GL_COLOR_BUFFER_BIT); // Show the clolor with display window color
glColor3f(1.0, 0.0, 0.0); // 物体颜色red
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
for (int i = 0; i < Q.size(); i++) {
glVertex3f(Q[i].x, Q[i].y, Q[i].z);
}
glEnd();
glColor3f(0.0, 0.0, 1.0); // 物体颜色blue
glBegin(GL_LINE_STRIP);
for (int i = 0; i < P.size(); i++) {
glVertex3f(P[i].x, P[i].y, P[i].z);
}
glEnd();
glFlush();
}
int main(int argc,char** argv)
{
point pt;
vector<point>::iterator it;
int num = 0;
float t = 0.01;
FILE *fp;
fp = fopen("2.txt", "r"); //将所有的数据点都保存在这个txt文档里
while (!feof(fp)) {
fscanf_s(fp, "%f %f %f", &pt.x, &pt.y, &pt.z);
Q.push_back(pt);
num++;
}
fclose(fp);
/*计算控制点坐标*/
for (int i = 0; i < num - 3; i++) {
pt.x = Q[i].x * pow(1 - t, 3) + Q[i + 1].x * 3 * t*pow(1 - t, 2) + Q[i + 2].x * 3 * pow(t, 2)*(1 - t) + Q[i + 3].x * pow(t, 3);
pt.y = Q[i].y * pow(1 - t, 3) + Q[i + 1].y * 3 * t*pow(1 - t, 2) + Q[i + 2].y * 3 * pow(t, 2)*(1 - t) + Q[i + 3].y * pow(t, 3);
pt.z = Q[i].z * pow(1 - t, 3) + Q[i + 1].z * 3 * t*pow(1 - t, 2) + Q[i + 2].z * 3 * pow(t, 2)*(1 - t) + Q[i + 3].z * pow(t, 3);
P.push_back(pt);
}
it = P.begin();
P.insert(it,Q[0]); //插入起始点
it = P.end();
P.insert(it,Q[num-1]); //插入末尾点
for (int i = 0; i < num; i++) {
cout << Q[i].x << "\t" << Q[i].y << "\t" << Q[i].z << endl;
}
cout << endl;
//输出三次贝塞尔曲线的控制点
for (int i = 0; i < P.size(); i++) {
cout << P[i].x << "\t" << P[i].y << "\t" << P[i].z << endl;
}
//接下来打印图形
glutInit(&argc, argv); //Initial GLUT 初始化
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //Set display mode, default set
glutInitWindowPosition(50, 50); //Set left-top display window position 窗口定位
glutInitWindowSize(winWidth, winHeight); //Set display window width and length 窗口大小
glutCreateWindow("三次贝塞尔曲线拟合如下:"); //Creat display window
init();
glutDisplayFunc(show);
glutMainLoop();
return 0;
}
4、运行结果:
蓝色的为拟合之后的曲线,红色的为原曲线。(视角不同,观察到的曲线也略有差异)
5、最后
以上仅为个人见解,不妥之处请多多指教。欢迎交流