OpenGL实现B样条曲线

一、vs2019安装OpenGL

https://blog.csdn.net/SouthWooden/article/details/108570410

二、PPT

https://www.cs.utexas.edu/~bajaj/graphics2012/cs354/lectures/lect11.pdf
在这里插入图片描述
p24

三、代码

#include <GL/glut.h>

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);
}

四、运行结果

在这里插入图片描述

总结

  • OpenGL绘图框架
  • Nurbs类使用
  • 求值器理解
  • 绘制点、直线、曲线
  • reshape函数设置

附bezier曲线代码

#include <GL/glut.h>
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;
}

感谢许多人分享自己的代码,站在巨人肩膀上,我才能看得更远

猜你喜欢

转载自blog.csdn.net/weixin_42785537/article/details/116885480
今日推荐