// newAG.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include "gl/gl.h"
#include "gl/glu.h"
#include "gl/glut.h"
#include <gl/glaux.h>
#ifndef CALLBACK
#define CALLBACK
#endif
int NurbsSurface = 0;
int NurbsPoints = 0;
int BezierSurface=0;// choose the Bezier surface
int BezierPoints=0;
#define YOZ_FIRSTDIMENTION 20
#define YOZ_SECONDDIMENTION 8
#define XOY_FIRSTDIMENTION 5
#define XOY_SECONDDIMENTION 8
#define MAXROW 36
#define MAXLIST 141
#define HBMAXLIST 140
GLUnurbsObj *theNurb[3]; //define three surfaces for these three styles
//the first is for Nurbs; the second is for Bezier; the last one is for Hermiter
GLfloat ctlpoints[MAXROW][MAXLIST][3]; //
GLfloat bezier[MAXROW][MAXLIST-1][3]={0};//reverse bezier surface's control points,and translate these points to
//another points so that it can call the gluNurbsface function to make a surface
GLfloat BezierToNurbsArray[4][4]={{1,4,1,0},{0,4,2,0},{0,2,4,0},{0,1,4,1}};
struct PDOT
{
GLfloat x;
GLfloat y;
};
PDOT P[YOZ_FIRSTDIMENTION][YOZ_SECONDDIMENTION],Q[XOY_FIRSTDIMENTION][XOY_SECONDDIMENTION];
void MakeWholeCtrPoints()
{
GLint i,j,k,h,num=0,g=0;
P[0][0].x=0;P[0][1].x=0.5;P[0][2].x=1.2;P[0][3].x=2.0;P[0][4].x=2.9;P[0][5].x=3.6;P[0][6].x=4.3;P[0][7].x=4.8296;
P[0][0].y=0;P[0][1].y=0.7;P[0][2].y=0.9;P[0][3].y=1.5;P[0][4].y=1.3;P[0][5].y=1.15;P[0][6].y=1.1;P[0][7].y=1.2941;
Q[0][0].x=0;Q[0][1].x=2;Q[0][2].x=3;Q[0][3].x=8;Q[0][4].x=10;Q[0][5].x=13;Q[0][6].x=16;Q[0][7].x=20;
Q[0][0].y=0;Q[0][1].y=1;Q[0][2].y=1.5;Q[0][3].y=3;Q[0][4].y=5;Q[0][5].y=2;Q[0][6].y=1.5;Q[0][7].y=0;
for (i=1;i<YOZ_FIRSTDIMENTION;i++)
{
for (j=0;j<YOZ_SECONDDIMENTION;j++)
{
P[i][j].x=P[i-1][j].x+4.8296;
P[i][j].y=P[i-1][j].y+1.2941;
}
}
for (i=1;i<XOY_FIRSTDIMENTION;i++)
{
for (j=0;j<XOY_SECONDDIMENTION;j++)
{
Q[i][j].x=Q[i-1][j].x+20;
Q[i][j].y=Q[i-1][j].y;
}
}
//
for (i=0;i<XOY_FIRSTDIMENTION;i++)
{
for (j=0;j<XOY_SECONDDIMENTION-1;j++)
{
for (k=0;k<YOZ_FIRSTDIMENTION;k++)
{
for (h=0;h<YOZ_SECONDDIMENTION-1;h++)
{
ctlpoints[num][g][0]=Q[i][j].x;
ctlpoints[num][g][1]=Q[i][j].y+P[k][h].x;
ctlpoints[num][g][2]=P[k][h].y;
g++;
}
if(k==YOZ_FIRSTDIMENTION-1 && h==YOZ_SECONDDIMENTION-1)
{
ctlpoints[num][g][0]=Q[i][j].x;
ctlpoints[num][g][1]=Q[i][j].y+P[k][h].x;
ctlpoints[num][g][2]=P[k][h].y;
g++;
}
}
g=0;
num++;
}
//
if (i==XOY_FIRSTDIMENTION-1 && j==XOY_SECONDDIMENTION-1)
{
for (k=0;k<YOZ_FIRSTDIMENTION;k++)
{
for (h=0;h<YOZ_SECONDDIMENTION-1;h++)
{
ctlpoints[num][g][0]=Q[i][j].x;
ctlpoints[num][g][1]=Q[i][j].y+P[k][h].x;
ctlpoints[num][g][2]=P[k][h].y;
g++;
}
if(k==YOZ_FIRSTDIMENTION-1 && h==YOZ_SECONDDIMENTION-1)
{
ctlpoints[num][g][0]=Q[i][j].x;
ctlpoints[num][g][1]=Q[i][j].y+P[k][h].x;
ctlpoints[num][g][2]=P[k][h].y;
g++;
}
}
}
}
}
//if flag==1,it means that the control points are translated from Bezier to Nurbs
//else flag==0,it means that the control points are translated from Hermiter to Nurbs
void ArrayMult(GLfloat L[4][3],GLfloat local[4][4])
{
GLfloat cop[4][3]={0}; //initial is so important
int i,j,k;
for (i=0;i<=3;i++)
{
for (j=0;j<=2;j++)
{
for (k=0;k<=3;k++)
{
cop[i][j]+=(local[i][k]*L[k][j]);
}
}
}
//save the result
for (i=0;i<=3;i++)
{
for (j=0;j<=2;j++)
{
L[i][j]=cop[i][j];
}
}
}
void TranBezierToNurbs()
{
MakeWholeCtrPoints();
int i,j,k,s;
GLfloat arrayt[4][3];
GLfloat local[4][4];
for (i=0;i<=3;i++)
{
for (j=0;j<=3;j++)
{
local[i][j]=BezierToNurbsArray[i][j];
}
}
for (i=0;i<MAXROW;i++)
{
for (j=0;j<MAXLIST-1;j+=4)
{
for (k=j;k<=j+3;k++)
{
for (s=0;s<=2;s++)
{
arrayt[k-j][s]=ctlpoints[i][k][s];
}
}
//translate
ArrayMult(&arrayt[0],&local[0]);
//struct the array
for (k=j;k<=j+3;k++)
{
for (s=0;s<=2;s++)
{
bezier[i][k][s]=arrayt[k-j][s];
}
}
}
}
}
void CALLBACK nurbsError(GLenum errorCode)
{
const GLubyte *estring;
estring = gluErrorString(errorCode);
fprintf (stderr, "Nurbs Error: %s\n", estring);
exit (0);
}
void init(void)
{
GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 100.0 };
glClearColor (1.0, 1.0, 0.3, 1.0);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
MakeWholeCtrPoints();
TranBezierToNurbs();
for (int i=0;i<=2;i++)
{
theNurb[i]=gluNewNurbsRenderer();
gluNurbsProperty(theNurb[i],GLU_SAMPLING_TOLERANCE,50.0);
// gluNurbsProperty(theNurb[i],GLU_DISPLAY_MODE,GLU_OUTLINE_PATCH);
gluNurbsProperty(theNurb[i],GLU_DISPLAY_MODE,GLU_FILL);
}
}
void display(void)
{
GLfloat uknots[MAXROW+4],vknots[MAXLIST+4],vbknots[MAXLIST-1+4] ;
int i;
for (i=0;i<MAXROW+4;i++) uknots[i]=float(i);
for (i=0;i<MAXLIST+4;i++) vknots[i]=float(i);
for (i=0;i<MAXLIST-1+4;i++) vbknots[i]=float(i);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
// glRotatef(60.0,1.0,1.0,1.0);
glRotatef(60.0,0.0,10.0,0.0);
// glScalef(0.03,0.03,0.03);
// glTranslatef(-50.0,-60.0,20.0);
// glScalef(0.003,0.003,0.003);
// glTranslatef(-100.0,-400.0,200.0);
if (NurbsSurface)
{
glScalef(0.03,0.03,0.03);
glTranslatef(-50.0,-60.0,20.0);
gluBeginSurface(theNurb[0]);
gluNurbsSurface(theNurb[0],
MAXROW+4,uknots,MAXLIST+4,vknots,
MAXLIST*3,3,&ctlpoints[0][0][0],
4,4,GL_MAP2_VERTEX_3);
gluEndSurface(theNurb[0]);
}
if (BezierSurface)
{
// glScalef(0.003,0.003,0.003);
glScalef(0.005,0.005,0.005);
glTranslatef(-100.0,-400.0,200.0);
// glRotatef(90,1.0,1.0,1.0);
TranBezierToNurbs();
gluBeginSurface(theNurb[1]);
gluNurbsSurface(theNurb[1],
MAXROW+4,uknots,MAXLIST-1+4,vbknots,
(MAXLIST-1)*3,3,&bezier[0][0][0],
4,4,GL_MAP2_VERTEX_3);
gluEndSurface(theNurb[1]);
}
if (NurbsPoints)
{
glScalef(0.03,0.03,0.03);
glTranslatef(-50.0,-60.0,20.0);
glPointSize(1.0);
glDisable(GL_LIGHTING);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POINTS);
for (int k=0;k<MAXROW;k++)
{
for (int h=0;h<MAXLIST;h++)
{
glVertex3f(ctlpoints[k][h][0],ctlpoints[k][h][1],ctlpoints[k][h][2]);
}
}
glEnd();
glEnable(GL_LIGHTING);
}
if (BezierPoints)
{
// glScalef(0.003,0.003,0.003);
glScalef(0.005,0.005,0.005);
glTranslatef(-100.0,-400.0,200.0);
// glTranslatef(-400.0,-400.0,200.0);
// glRotatef(90,1.0,1.0,1.0);
glPointSize(1.0);
glDisable(GL_LIGHTING);
glColor3f(0.0,0.0,1.0);
// glScalef(0.5,0.5,0.5);
glBegin(GL_POINTS);
for (int k=0;k<MAXROW;k++)
{
for (int h=0;h<MAXLIST-1;h++)
{
glVertex3f(bezier[k][h][0],bezier[k][h][1],bezier[k][h][2]);
}
}
glEnd();
glEnable(GL_LIGHTING);
}
glPopMatrix();
glFlush();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (45.0, (GLdouble)w/(GLdouble)h, 3.0, 8.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef (0.0, 0.0, -5.0);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 'c':
//nurbs points or surface
case 'B':
NurbsSurface=!NurbsSurface;
glutPostRedisplay();
break;
case 'b':
NurbsPoints=!NurbsPoints;
glutPostRedisplay();
break;
//bezier points or su
- 1
- 2
- 3
前往页