图形学实验五曲线生成算法

实验五  曲线生成算法

实验类型:设计型   实验学时:2实验要求:必修

一、实验目的

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

二、实验内容

1 分析空间曲线生成算法的原理,绘制其程序流程图;

2结合示范代码了解曲线生成原理与算法实现,尤其是Bezier曲线;

三、实验原理

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

三次Bezier曲线,有四个控制点,其数学表示如下:

 

四、实验示范代码(略)

五、实验步骤

1 在Windows xp/win7操作环境下,启动VC;

2 建立W32 Console Application 的应用工程;

3 建立源程序编辑环境,进行编辑源程序。

4 调试运行程序,完成实验。

六、实验结果处理

演示结果并保存相关文件。

七、实验注意事项

注意编程环境的配置,即在Windows环境下,OpenGL扩展库相关文件的配置,把头文件“GL.H”、库文件“OPENGL32.LIB”和动态链接库“OPENGL32.DLL”配置到相应的目录下。

八、预习与思考题

预习:阅读课本相关内容,仔细阅读示范代码。

思考题:如何B样条曲线的生成算法。

九、实验报告要求

1、实验报告中应包括相关操作步骤和程序代码和运行效果截图。

2.书写实验报告时要结构合理,层次分明,在分析描述的时候,需要注意语言的流畅

基础:

升级1:

 基础代码:

#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 Berzier Curve!\n");
	
}


void Reshape(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 mouse(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(Reshape);
	glutMouseFunc(mouse);
	glutMainLoop();
	return 0;
}

 升级1代码:

#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(6);//设定点的大小
	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++)
	{
		if(num==11)//设定曲线部分颜色为白色
		glColor3f(1.0f,1.0f,1.0f);
		else
		glColor3f(1.0f,1.0f,0.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 Berzier Curve!\n");
	
}


void Reshape(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 mouse(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(Reshape);
	glutMouseFunc(mouse);
	glutMainLoop();
	return 0;
}

结果即为实验要求!不再展示!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北溟南风起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值