OpenGL绘制简单的参数曲线——三阶Bezier曲线(二)

  今天我们来介绍三次Bezier曲线,这曲线网上资料非常多,我这里只是简单介绍下原理。

  在二维空间中(三维也类似),给定n+1个点P0、P1、... 、Pn。参数t的n次的Bezier曲线是:

图1

  我们根据上面式子可以推出一阶、二阶、三阶贝塞尔曲线,下面是一阶贝塞尔曲线:

图2

  下面是二阶贝塞尔曲线,表示的是从P0P1线段取Q0,P1P2线段取Q1,每一个Q0Q1都是曲线的切向量:

图3

  下面是三阶贝塞尔曲线,表示的是从P0P1线段取Q0,P1P2线段取Q1,P2P3线段取Q2,再从Q0Q1取R0,Q1Q2取R1,每一个R0R1都是曲线的切向量:

图4

  这样就给出了公式,下面贴出三阶Beizer曲线的代码,同样可以手动调节参数,大家参考一下。

#include <math.h>
#include <gl/glut.h>
#include <iostream>
using namespace std;

GLfloat xCoord[4], yCoord[4];
int num = 0;  

/*计算Bezier曲线*/
void Bezier(int n)
{
	float f1, f2, f3, f4;
	float deltaT = 1.0 / n;
	float T;

	glBegin(GL_LINE_STRIP);
	for (int i = 0; i <= n; i++) {  

		T = i * deltaT;

		f1 = (1-T) *(1- T) * (1-T);
		f2 = 3 * T * (1-T) * (1- T);
		f3 = 3 * T * T * (1-T);
		f4 = T * T * T;  

		glVertex2f( f1*xCoord[0] + f2*xCoord[1] + f3*xCoord[2] + f4*xCoord[3],
			f1*yCoord[0] + f2*yCoord[1] + f3*yCoord[2] + f4*yCoord[3]);
	}
	glEnd();
}  

/*用鼠标进行绘制,完成后可改变控制点,
	wsad控制第二个控制点,ijkl控制第三个控制点*/
void display(){
	glClear(GL_COLOR_BUFFER_BIT);  

	glLineWidth(1.5);
	glColor3f (1.0, 0.0, 0.0);
	glBegin(GL_LINE_STRIP);
	for (int i = 0; i < num; i++)
		glVertex3f (xCoord[i], yCoord[i], 0.0);
	glEnd();  

	glColor3f (0.0, 0.0, 1.0);
	if (num == 4)
		Bezier(20);  

	glFlush();
	glutSwapBuffers();
}  

void init()
{
	glClearColor(1.0, 1.0, 1.0, 0.0);
	glShadeModel(GL_FLAT);
}  

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

void mouse(int button, int state, int x, int y)
{
	if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
	{
		if (num == 4)
			num = 0;  

		xCoord[num] = x;
		yCoord[num] = y;
		num++;
		glutPostRedisplay();
	}
}  

void keyboard(unsigned char key, int x, int y)
{
	if (key == ‘w‘ && num == 4)
		yCoord[1] -= 5.0;

	if (key == ‘s‘ && num == 4)
		yCoord[1] += 5.0;

	if (key == ‘a‘ && num == 4)
		xCoord[1] -= 5.0;

	if (key == ‘d‘ && num == 4)
		xCoord[1] += 5.0;

	if (key == ‘i‘ && num == 4)
		yCoord[2] -= 5.0;

	if (key == ‘k‘ && num == 4)
		yCoord[2] += 5.0;

	if (key == ‘j‘ && num == 4)
		xCoord[2] -= 5.0;

	if (key == ‘l‘ && num == 4)
		xCoord[2] += 5.0;

	glutPostRedisplay();
}

int  main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB );
	glutInitWindowSize (450, 450);
	glutInitWindowPosition (200, 200);
	glutCreateWindow ("hello");
	init ();  

	glutDisplayFunc(display);
	glutReshapeFunc(myReshape);
	glutKeyboardFunc(keyboard);
	glutMouseFunc(mouse);  

	glutMainLoop();
	return 0;
}

  

时间: 2024-10-12 16:41:56

OpenGL绘制简单的参数曲线——三阶Bezier曲线(二)的相关文章

OpenGL绘制简单的参数曲线——两点三次Hermite曲线(一)

网上这类曲线绘制的文章非常多,但是大多都是代码一贴就完事了,甚至连参数怎么调也没说清楚.我翻阅了不少资料,这里做个汇总,主要也就介绍一下几类简单的曲线绘制,如Hermite曲线.Bezier曲线等.今天先说说Hermite曲线,基本上最常见的就是两点三次的Hermite曲线了. 按照惯例,我们先来介绍一下Hermite曲线的原理.Hermite曲线是给定曲线段的两个端点坐标以及两端点处的切线矢量来描述的曲线.平面上一条三次参数曲线可以表示为: 图1 空间Hermite曲线跟上述类似,只是加一个z

OpenGL绘制简单场景,实现旋转缩放平移和灯光效果

本项目实现了用OpenGL绘制一个简单场景,包含正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码,有详细注释.适合初学者熟悉opengl使用. 开发情况 开发环境VS2012+OpenGL 开发平台 Intel core i5,Intel HD Graphics Family 本项目实现了绘制一个场景(包括立方体.球体.网格),对各物体实现平移.旋转.缩放功能,添加了光源并简单设置了物体材质. 本项目示例代码下载(里面有详细注释) 感谢nehe的框架! 场景介绍 初始

OpenGL绘制简单的时钟(首发测试)

编辑器 vs2012 1 #include <windows.h> 2 #include <GL/glut.h>//本来OpenGL程序一般还要包含<GL/gl.h>和<GL/glu.h>, 3 //但GLUT的头文件中已经自动将这两个文件包含了,不必再次包含. 4 #include <math.h> 5 #include<time.h> 6 7 const GLfloat Pi = 3.1415926536; 8 const GLf

简单而粗暴的方法画任意阶数Bezier曲线

简单而粗暴的方法画任意阶数Bezier曲线 虽然说是任意阶数,但是嘞,算法原理是可以到任意阶数,计算机大概到100多阶就会溢出了 Bezier曲线介绍 本文代码 背景 在windows的OpenGL环境中,使用鼠标在屏幕上选点,并以点为基础画出Bezier曲线 初始化 鼠标操作 3阶以内Bezier曲线 n阶Bezier曲线 初始化 创建窗口,初始化大小.显示模式.添加显示和鼠标等回调函数,设置背景颜色等. 完成之后,定义两个全局的int类型的vector 用于存储鼠标在窗口中选择的点.同时定义

7.5.5编程实例-Bezier曲线曲面绘制

(a)Bezier曲线                         (b) Bezier曲面 1. 绘制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); glShadeMod

opengl使用现在比较常用的方法来绘制简单几何图元

上一篇文章中也使用了比较老的方法glBegin 和 glEnd的方法来绘制了简单的集合图元,现在使用比较新的而且更高效的方法来绘制简单的集合图元. 这种方法与以前方法的不同点在对数据的处理上,glBegin 和 glEnd是要给出数据,然后直接来进行绘制,然而新的方法是现将数据保存到显存中,然后直接一个绘制命令,就可以直接从显卡内存中直接读取数据进行绘制,效率更高而且更方便. #include <GL/glew.h> #include <GL/freeglut.h> #includ

Bezier曲线绘制 B样条绘制

/*输入点的个数是可以手动改动的,此程序中输入点的最大值设置为. *同时,程序实现了键盘的交互,用来控制程序运行过程中的退出.重画等 */ #include<GL/glut.h> #include<stdlib.h> int W,H; //屏幕的大小 int N =-1; //贝赛尔曲线的幂次 GLfloat Bfunc[15]={0.0}; //Bernstein多项式的值的数组 GLfloat point[15][2]={0.0}; //存储控制点的坐标 void Init()

OpenGL学习-------绘制简单的几何图形

本次课程所要讲的是绘制简单的几何图形,在实际绘制之前,让我们先熟悉一些概念. 一.点.直线和多边形我们知道数学(具体的说,是几何学)中有点.直线和多边形的概念,但这些概念在计算机中会有所不同.数学上的点,只有位置,没有大小.但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点.另一方面,无论图形输出设备(例如,显示器)如何精确,始终不能输出一个无穷小的点.一般情况下,OpenGL中的点将被画成单个的像素(像素的概念,请自己搜索之~),虽然它可能足够小,但并不会是无穷小.同一像素上,Op

Bezier曲线原理—动态解释

Bezier曲线原理 贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线.一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的.贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等.在Flash4中还没有完整的曲线工具,而在Flash5里面已经提供出贝塞尔曲线工具.贝塞尔曲线于19