OpenGL中如何绘制Bezier曲线和NURBS曲线

一、Bezier曲线

      主要注意两个函数:glMap1和glEvalCoord1。

1.void glMap1{fd}(GLenum target,TYPE u1,TYPE u2,GLint stride, GLint order,const TYPE *points);
功能:定义求值器。 

参数:target:指出了控制顶点的意义以及在points参数中需要提供多少值。

         points:可以指向控制点集、RGBA颜色值或是纹理坐标串等。

         u1、u2:限定了变量U的取值范围,通常是从0变化到1。

         stride:表示跨度(在每块存储区内浮点数或双精度数的个数,即两个控制点间的偏移量)。

         order:阶数,等于次数加1,与控制点数相等。

2.void glEvalCoord1{fd}[v](TYPE u)。
功能:该函数将产生曲线坐标值并将其绘制。

参数:u:为定义域内的任意值,每调用一次将只产生一个坐标,此坐标值也是任意的。

      但目前较多采用的是定义均匀间隔曲线坐标值,依次调用glMapGrid1*()和glEvalMesh1()可以获得等间隔值。这两个函数分别用来定义一个一维网格和计算相应的坐标值。

      另外,曲线定义后必须再glEnable()函数显式启动后才能起作用,其参数与target保持一致。在使用完毕后通过glDisable()函数将其关闭。

view plaincopy to clipboardprint?
01.#include <GL/glut.h>  
02.#include <stdlib.h>  
03.GLfloat ctrlpoints[9][3] = {{0,-0.2,0},{-1.2,-0.5,0},{-1.6,-1,0},{-1.4,-1.5,0},  
04.{-1,-2.2,0},{-0.5,-2.7,0},{-0.35,-3.2,0},{-0.6,-3.7,0},{-1.6,-4.2,0}};//控制点  
05. 
06.void init(void)  
07.{  
08.   glClearColor(0.0, 0.0, 0.0, 0.0);  
09.   glShadeModel(GL_FLAT);  
10.   glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 9, &ctrlpoints[0][0]);  
11.   glEnable(GL_MAP1_VERTEX_3);  
12.}  
13.void display(void)  
14.{  
15.   int i;  
16.   glClear(GL_COLOR_BUFFER_BIT);  
17.   glColor3f(1.0, 1.0, 1.0);  
18.   glBegin(GL_POINTS);//(GL_LINE_STRIP);  
19.      for (i = 0; i <= 30; i++)   
20.         glEvalCoord1f((GLfloat) i/30.0);  
21.   glEnd();  
22.   /* The following code displays the control points as dots. */ 
23.   glPointSize(5.0);  
24.   glColor3f(1.0, 1.0, 0.0);  
25.   glBegin(GL_POINTS);  
26.      for (i = 0; i < 9; i++)   
27.         glVertex3fv(&ctrlpoints[i][0]);  
28.   glEnd();  
29.   glFlush();  
30.}  
31.void reshape(int w, int h)  
32.{  
33.   glViewport(0, 0, (GLsizei) w, (GLsizei) h);  
34.   glMatrixMode(GL_PROJECTION);  
35.   glLoadIdentity();  
36.   if (w <= h)  
37.      glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,   
38.               5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);  
39.   else 
40.      glOrtho(-5.0*(GLfloat)w/(GLfloat)h,   
41.               5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);  
42.   glMatrixMode(GL_MODELVIEW);  
43.   glLoadIdentity();  
44.}  
45.void keyboard(unsigned char key, int x, int y)  
46.{  
47.   switch (key) {  
48.      case 27:  
49.         exit(0);  
50.         break;  
51.   }  
52.}  
53.int main(int argc, char** argv)  
54.{  
55.   glutInit(&argc, argv);  
56.   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);  
57.   glutInitWindowSize (500, 500);  
58.   glutInitWindowPosition (100, 100);  
59.   glutCreateWindow (argv[0]);  
60.   init ();  
61.   glutDisplayFunc(display);  
62.   glutReshapeFunc(reshape);  
63.   glutKeyboardFunc (keyboard);  
64.   glutMainLoop();  
65.   return 0;  
66.} 
#include <GL/glut.h>
#include <stdlib.h>
GLfloat ctrlpoints[9][3] = {{0,-0.2,0},{-1.2,-0.5,0},{-1.6,-1,0},{-1.4,-1.5,0},
{-1,-2.2,0},{-0.5,-2.7,0},{-0.35,-3.2,0},{-0.6,-3.7,0},{-1.6,-4.2,0}};//控制点

void init(void)
{
   glClearColor(0.0, 0.0, 0.0, 0.0);
   glShadeModel(GL_FLAT);
   glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 9, &ctrlpoints[0][0]);
   glEnable(GL_MAP1_VERTEX_3);
}
void display(void)
{
   int i;
   glClear(GL_COLOR_BUFFER_BIT);
   glColor3f(1.0, 1.0, 1.0);
   glBegin(GL_POINTS);//(GL_LINE_STRIP);
      for (i = 0; i <= 30; i++)
         glEvalCoord1f((GLfloat) i/30.0);
   glEnd();
   /* The following code displays the control points as dots. */
   glPointSize(5.0);
   glColor3f(1.0, 1.0, 0.0);
   glBegin(GL_POINTS);
      for (i = 0; i < 9; i++)
         glVertex3fv(&ctrlpoints[i][0]);
   glEnd();
   glFlush();
}
void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) 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();
}
void keyboard(unsigned char key, int x, int y)
{
   switch (key) {
      case 27:
         exit(0);
         break;
   }
}
int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (500, 500);
   glutInitWindowPosition (100, 100);
   glutCreateWindow (argv[0]);
   init ();
   glutDisplayFunc(display);
   glutReshapeFunc(reshape);
   glutKeyboardFunc (keyboard);
   glutMainLoop();
   return 0;
}
 

 

二、NURBS曲线

      主要注意函数:
1.void gluNurbsCurve(GLUnurbsObj *nobj, GLint nknots, GLfloat *knot, Glint stride, GLfloat *ctlarray, GLint order,GLenum type)

功能:定义曲线形状。
参数:nobj:指向NURBS对象的指针。
     nknots:节点数,节点数=控制点数+阶数。
     knot:nknots数组非递减节点值。
     stride:跨度,相邻控制点的偏移量。
     Ctlarry:指向NURBS的控制点数组的指针。
     order:NURBS曲线的阶数,阶数=次数+1。
     type:曲线、面类型。

2.void gluNurbsProperty(GLUnurbsObj* nobj, GLenum property, GLfloat value)

功能:设置NURBS属性。

参数:nobj:指向NURBS对象的指针。
     property:需设置的属性。
     value:设置指定属性的值。

3.gluBeginCurve、gluEndCurve限定NURBS曲面。返回值均为void,参数均为GLUnurbsObj* nobj,为指向NURBS对象的指针。

view plaincopy to clipboardprint?
01.#include <windows.h>  
02.#include <GL/glut.h>  
03. 
04.GLUnurbsObj *theNurb;  
05.GLfloat ctrlpoints[9][3] = {{0,-0.2,0},{-1.2,-0.5,0},{-1.6,-1,0},{-1.4,-1.5,0},  
06.{-1,-2.2,0},{-0.5,-2.7,0},{-0.35,-3.2,0},{-0.6,-3.7,0},{-1.6,-4.2,0}};//控制点  
07.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},  
08.{-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}};  
09. 
10.void myInit(void)  
11.{  
12.    glClearColor(1.0,1.0,1.0,0.0);//设置背景色  
13.    theNurb = gluNewNurbsRenderer();//创建NURBS对象theNurb  
14.    gluNurbsProperty(theNurb,GLU_SAMPLING_TOLERANCE,10);  
15.}  
16./*绘制曲线*/ 
17.void myDisplay(void)  
18.{  
19.    int i;  
20.    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);  
21.    glColor3f(0.0,0.0,0.0);  
22.    glLineWidth(3.0);  
23.    /*绘制曲线*/ 
24.    gluBeginCurve(theNurb);  
25.    gluNurbsCurve(theNurb,13,knots,3,&ctrlpoints[0][0],4,GL_MAP1_VERTEX_3);  
26.    gluNurbsCurve(theNurb,13,knots,3,&color[0][0],4,GL_MAP1_COLOR_4);  
27.    gluEndCurve(theNurb);  
28.    /*绘制点*/ 
29.    glColor3f(1.0,0.0,0.0);  
30.    glPointSize(5.0);  
31.    glBegin(GL_POINTS);  
32.    for(i = 0;i < 9;i++)  
33.        glVertex2fv(&ctrlpoints[i][0]);  
34.    glEnd();  
35.    glutSwapBuffers();  
36.}  
37.void myReshape(GLsizei w,GLsizei h)  
38.{  
39.    glViewport(0,0,w,h);  
40.    glMatrixMode(GL_PROJECTION);  
41.    glLoadIdentity();  
42.    if(w <=h)  
43.        glOrtho(-10.0,10.0,-10.0*(GLfloat)h/(GLfloat)w,10.0*(GLfloat)h/  
44. 
45.(GLfloat)w,-10.0,10.0);  
46.    else 
47.        glOrtho(-10.0*(GLfloat)w/(GLfloat)h,10.0*(GLfloat)w/(GLfloat)h,-  
48. 
49.10.0,10.0,-10.0,10.0);  
50.    glMatrixMode(GL_MODELVIEW);  
51.    glLoadIdentity();  
52.    glTranslatef(0.0,0.0,-9.0);  
53.}  
54.int main(int argc,char ** argv)  
55.{  
56.    glutInit(&argc,argv);  
57.    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);  
58.    glutInitWindowSize(600,400);  
59.    glutInitWindowPosition(200,200);  
60.    glutCreateWindow("NURBS curve");  
61.    /*绘制与显示*/ 
62.    myInit();  
63.    glutReshapeFunc(myReshape);  
64.    glutDisplayFunc(myDisplay);  
65.    glutMainLoop();  
66.    return(0);  
67.} 
#include <windows.h>
#include <GL/glut.h>

GLUnurbsObj *theNurb;
GLfloat ctrlpoints[9][3] = {{0,-0.2,0},{-1.2,-0.5,0},{-1.6,-1,0},{-1.4,-1.5,0},
{-1,-2.2,0},{-0.5,-2.7,0},{-0.35,-3.2,0},{-0.6,-3.7,0},{-1.6,-4.2,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}};

void myInit(void)
{
 glClearColor(1.0,1.0,1.0,0.0);//设置背景色
 theNurb = gluNewNurbsRenderer();//创建NURBS对象theNurb
 gluNurbsProperty(theNurb,GLU_SAMPLING_TOLERANCE,10);
}
/*绘制曲线*/
void myDisplay(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);
 /*绘制点*/
 glColor3f(1.0,0.0,0.0);
 glPointSize(5.0);
 glBegin(GL_POINTS);
 for(i = 0;i < 9;i++)
  glVertex2fv(&ctrlpoints[i][0]);
 glEnd();
 glutSwapBuffers();
}
void myReshape(GLsizei w,GLsizei h)
{
 glViewport(0,0,w,h);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 if(w <=h)
  glOrtho(-10.0,10.0,-10.0*(GLfloat)h/(GLfloat)w,10.0*(GLfloat)h/

(GLfloat)w,-10.0,10.0);
 else
  glOrtho(-10.0*(GLfloat)w/(GLfloat)h,10.0*(GLfloat)w/(GLfloat)h,-

10.0,10.0,-10.0,10.0);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 glTranslatef(0.0,0.0,-9.0);
}
int main(int argc,char ** argv)
{
 glutInit(&argc,argv);
 glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
 glutInitWindowSize(600,400);
 glutInitWindowPosition(200,200);
 glutCreateWindow("NURBS curve");
 /*绘制与显示*/
 myInit();
 glutReshapeFunc(myReshape);
 glutDisplayFunc(myDisplay);
 glutMainLoop();
 return(0);
}

 

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wuzoujing/archive/2009/11/30/4900636.aspx

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wuzoujing/archive/2009/11/30/4900636.aspx

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值