https://blog.csdn.net/SouthWooden/article/details/108570410
https://www.cs.utexas.edu/~bajaj/graphics2012/cs354/lectures/lect11.pdf
#include
GLUnurbsObj* theNurb;
GLfloat ctrlpoints[11][3] =
{ { 1.0, 2.0, 0.0}, { 1.6, 0.9, 0.0},{2.4, 2.1, 0.0}, {3.6, 1.3, 0.0},{4.5, 0.6, 0.0},
{5.3, -0.3, 0.0},{5.9, -1.4, 0.0},{6.9, -0.5, 0.0},{7.7, 0.6, 0.0},{8.5, 1.5, 0.0},
{9.3, 3.7, 0.0} };
/*GLfloat color[9][3] = { {1.0,0.0,0.0},{1.0,1.0,0.0},{0.0,1.0,0.0},{-1.0,1.0,0.0},
{-1.0,0.0,0.0},{-1.0,-1.0,0.0},{0.0,-1.0,0.0},{1.0,-1.0,0.0},{1.0,-1.0,0.0} };*/
GLfloat knots[15] = { 0.0, 0.0, 0.0, 0.0,
0.2, 0.4, 0.4, 0.6,
0.8, 0.8, 0.8,
1.0, 1.0, 1.0, 1.0 };
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);//设置背景色
theNurb = gluNewNurbsRenderer();//创建NURBS对象theNurb
gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 10);
}
/*绘制曲线*/
void Display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glLineWidth(3.0);
/*绘制曲线*/
gluBeginCurve(theNurb);
gluNurbsCurve(theNurb, 13, knots, 3, &ctrlpoints[0][0], 4, GL_MAP1_VERTEX_3);
//gluNurbsCurve(theNurb, 13, knots, 3, &color[0][0], 4, GL_MAP1_COLOR_4);
gluEndCurve(theNurb);
/*绘制控制多边形*/
glLineWidth(1);//设置栅格化线条的宽度
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for (i = 0; i < 11; i++)
glVertex3fv(&ctrlpoints[i][0]);
glEnd();
/*绘制点*/
glColor3f(1.0, 0.0, 0.0);
glPointSize(5.0);
glBegin(GL_POINTS);
for (i = 0; i < 11; i++)
glVertex2fv(&ctrlpoints[i][0]);
glEnd();
glutSwapBuffers();
}
void Reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 10.0, -5.0 * (GLfloat)h / (GLfloat)w, 5.0 * (GLfloat)h /
(GLfloat)w, -5.0, 5.0);
else
glOrtho(-1.0 * (GLfloat)w / (GLfloat)h, 10.0 * (GLfloat)w / (GLfloat)h, -
5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void keyboard(unsigned char key, int x, int y) //key 为键盘按键的ASCII码
{
switch (key)
{
case 'x':
case 'X':
case 27: //ESC键
exit(0);
break;
default:
break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(600, 400);
glutInitWindowPosition(200, 200);
glutCreateWindow("三次B样条曲线");
/*绘制与显示*/
init();
glutReshapeFunc(Reshape);
glutKeyboardFunc(keyboard);
glutDisplayFunc(Display);
glutMainLoop();
return(0);
}
#include
GLfloat ctrlpoints[4][3] =
{ { -4.0, -4.0, 0.0}, { -2.0, 3.0, 0.0},{2.0, 4.5, 0.0}, {3.0, -3.0, 0.0} };
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glShadeModel(GL_FLAT);
//下行用于定义曲线函数
glEnable(GL_MAP1_VERTEX_3); //将当前曲线函数激活
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]);
}
//void glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
//将控制点坐标映射为曲线坐标
//参数1:GL_MAP1_VERTEX_3,3维点坐标
//参数2和3:控制参数t或u的取值范围[0, 1]
//参数4:曲线内插值点间的步长3————3维坐标
//参数5:曲线间的补偿为顶点数4个————总步长为12
//参数6:控制点二维数组首元素地址
void display(void)
{
int i;
glClear(GL_COLOR_BUFFER_BIT);
//下面用求值器按10等分计算Bezier曲线上的点
glColor3f(0.0, 0.0, 0.0);
glLineWidth(5);//设置栅格化线条的宽度
//glBegin来指明如何使用这些顶点
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)//10控制曲线的光滑程度,也就是打点的密集程度
glEvalCoord1f((GLfloat)i / 30.0); //相当于调用了glVertex*()
glEnd();
//下面绘制控制多边形
glLineWidth(1);//设置栅格化线条的宽度
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_LINE_STRIP);
for (i = 0; i < 4; i++)
glVertex3fv(&ctrlpoints[i][0]);
glEnd();
glFlush();
}
void reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-5.0, 5.0, -5.0 * (GLfloat)h / (GLfloat)w, 5.0 * (GLfloat)h / (GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0 * (GLfloat)w / (GLfloat)h, 5.0 * (GLfloat)w / (GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);//显示模式
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow("三次bezier曲线");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}
感谢许多人分享自己的代码,站在巨人肩膀上,我才能看得更远