前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实验10 Bezier曲线生成

实验10 Bezier曲线生成

作者头像
步行者08
发布2020-10-29 10:10:30
1.1K0
发布2020-10-29 10:10:30
举报
文章被收录于专栏:图形学与OpenGL图形学与OpenGL

1.实验目的:

  • 了解曲线的生成原理;
  • 掌握几种常见的曲线生成算法,利用VC+OpenGL实现Bezier曲线生成算法。

2.实验内容:

(1)结合示范代码了解曲线生成原理与算法实现,尤其是Bezier曲线。 (2)调试、编译、修改示范程序。

3.实验原理:

Bezier曲线是通过一组多边形折线的顶点来定义的。如果折线的顶点固定不变,则由其定义的Bezier曲线是唯一的。在折线的各顶点中,只有第一点和最后一点在曲线上且作为曲线的起始点和终止点,其他的点用于控制曲线的形状及阶次。曲线的形状趋向于多边形折线的形状,要修改曲线,只要修改折线的各顶点就可以了。因此,多边形折线又称Bezier曲线的控制多边形,其顶点称为控制点。 三次Bezier曲线,有四个控制点,其数学表示如下:

在这里插入图片描述
在这里插入图片描述

4.实验代码:

代码语言:javascript
复制
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

using namespace std;

struct Point
{
	int x, y;
};

Point pt[4], bz[11];
vector<Point> vpt;
bool bDraw;
int nInput;

void CalcBZPoints()
{
	float a0,a1,a2,a3,b0,b1,b2,b3;
	a0=pt[0].x;
	a1=-3*pt[0].x+3*pt[1].x;
	a2=3*pt[0].x-6*pt[1].x+3*pt[2].x;
	a3=-pt[0].x+3*pt[1].x-3*pt[2].x+pt[3].x;
	b0=pt[0].y;
	b1=-3*pt[0].y+3*pt[1].y;
	b2=3*pt[0].y-6*pt[1].y+3*pt[2].y;
	b3=-pt[0].y+3*pt[1].y-3*pt[2].y+pt[3].y;

	float t = 0;
	float dt = 0.01;
	for(int i = 0; t<1.1; t+=0.1, i++)
	{
		bz[i].x = a0+a1*t+a2*t*t+a3*t*t*t;
		bz[i].y = b0+b1*t+b2*t*t+b3*t*t*t;
	}
}

void ControlPoint(vector<Point> vpt)
{
	glPointSize(2);
	for(int i=0; i<vpt.size(); i++)
	{
		glBegin (GL_POINTS);
		glColor3f (1.0f, 0.0f, 0.0f);   
glVertex2i (vpt[i].x,vpt[i].y);
		glEnd ();
	}
}

void PolylineGL(Point *pt, int num)
{
	glBegin (GL_LINE_STRIP);
	for(int i=0;i<num;i++)
	{		
		glColor3f (1.0f, 1.0f, 1.0f);   
		glVertex2i (pt[i].x,pt[i].y);		
	}
	glEnd ();
}

void myDisplay()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f (1.0f, 1.0f, 1.0f); 
	if (vpt.size() > 0)
	{
		ControlPoint(vpt);
	}

	if(bDraw)
	{
		PolylineGL(pt, 4);
		CalcBZPoints();
		PolylineGL(bz, 11);
	}

	glFlush();
}

void Init()
{
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_SMOOTH);

	printf("Please Click left button of mouse to input control point of Bezier Curve!\n");
}

void myReshape(int w, int h)
{
	glViewport(0, 0, (GLsizei) w,  (GLsizei) h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}

void myMouse(int button, int state, int x, int y)
{
	switch (button)
	{
	case GLUT_LEFT_BUTTON:
		if (state == GLUT_DOWN) 
		{
			if (nInput == 0)
			{
				pt[0].x = x;
				pt[0].y = 480 - y;
				nInput = 1;
				vpt.clear();
				vpt.push_back(pt[0]);

				bDraw = false;
				glutPostRedisplay();
			}
			else if (nInput == 1) 
			{
				pt[1].x = x;
				pt[1].y = 480 - y;
				vpt.push_back(pt[1]);
				nInput = 2;
				glutPostRedisplay();
			}
			else if (nInput == 2) 
			{
				pt[2].x = x;
				pt[2].y = 480 - y;
				vpt.push_back(pt[2]);
				nInput = 3;
				glutPostRedisplay();
			}
			else if (nInput == 3) 
			{
				pt[3].x = x;
				pt[3].y = 480 - y;
				bDraw = true;
				vpt.push_back(pt[3]);
				nInput = 0;
				glutPostRedisplay();
			}
		}
		break;
	default:
		break;
	}
}

int main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
	glutInitWindowPosition(100, 100);
	glutInitWindowSize(640, 480);
	glutCreateWindow("Hello World!");

	Init();
	glutDisplayFunc(myDisplay);
	glutReshapeFunc(myReshape);
	glutMouseFunc(myMouse);
	glutMainLoop();
	return 0;
}

运行结果如图A.10(a)所示。

在这里插入图片描述
在这里插入图片描述

图A.10(a)Bezier曲线

5.实验提高

模仿上述代码,以( 10, 5, 0 ),( 5, 10, 0 ),( -5, 15, 0 ),( -10, -5, 0 ),( 4, -4, 0 ),( 10, 5, 0 ), ( 5, 10, 0 ), ( -5, 15, 0 ), ( -10, -5, 0 ),( 10, 5, 0 )为控制点,将其转变为B样条曲线生成算法,见图A.10(b)。

在这里插入图片描述
在这里插入图片描述

图A.10(b)B样条曲线

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-10-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.实验目的:
  • 2.实验内容:
  • 3.实验原理:
  • 4.实验代码:
  • 5.实验提高
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档