此程序主要分为两部分,一部分是抽象旋转曲面和直纹面的类,另一部分是视图界面的类组织,二者通过在视图界面定义数据成员建立联系。
第一部分:
旋转曲面类:
class Revsurf:public bspline,public Mesh //旋转曲面
{
public:
Revsurf(Point3* pt1,int num,int uu,int vv,int mm); //构造函数
~Revsurf();
public:
void writeMesh(char *fname); //将生成的点、法线、面片写入文件
void makefaces(); //生成面片及索引
void makenormals(); //生成法线及索引
int ctlpt_num; //控制点的个数
int v; //经度方向
int u; //纬度方向
Point3 *ctlpt; //保存控制点
void makepoints(); //生成点及索引
};
Revsurf::Revsurf(Point3 *pt1,int num,int uu,int vv,int mm) //旋转曲面
:ctlpt(pt1),ctlpt_num(num),u(uu),v(vv),bspline(mm,num)
{
numVerts=u*v;
numNorms=u*v;
numFaces=(u-1)*v;
pt=new Point3[numVerts];
norm=new Vector3[numNorms];
face=new Face[numFaces];
}
Revsurf::~Revsurf()
{
}
/******************************旋转曲面生成顶点*********************************/
void Revsurf::makepoints()
{
int i=0,j=0,k=0;
float t=0,x=0,y=0,z=0;
Point3 *p; //记录两条u线的点
p=new Point3[u];
//细节处理1e-5
for(t=knot[0]+1e-5;i<u;t+=knot[ctlpt_num+m-1]/(float)(u-1)-1e-5) //采集两条u线的点
{
p[i].set(0,0,0);
for(k=0;k<ctlpt_num;k++)
{
p[i].x+=ctlpt[k].x*getbsplineValue(k,m,t,knot);
p[i].y+=ctlpt[k].y*getbsplineValue(k,m,t,knot);
p[i].z+=ctlpt[k].z*getbsplineValue(k,m,t,knot);
}
i++;
}
glBegin(GL_LINE_STRIP);
for(i=0;i<u;i++)
glVertex3f(p[i].x,p[i].y,p[i].z);
glEnd();
for(j=0;j<v;j++) //生成网格点i*v+j
for(i=0;i<u;i++)
{
x=p[i].x*cos(j/(float)v*2*PI);
y=p[i].y;
z=p[i].x*sin(j/(float)v*2*PI);
pt[j*u+i].set(x,y,z);
pt[j*u+i].set(j*u+i);
}
delete[] p;
p=NULL;
}
/******************************旋转曲面生成法线*********************************/
void Revsurf::makenormals()
{
Vector3 va(0,0,0),vb(0,0,0);
int i=0,j=0;
for(;j<v-1;j++)
{
for(i=0;i<u-1;i++)
{
va.set(pt[j*u+i+1].x-pt[j*u+i].x,pt[j*u+i+1].y-pt[j*u+i].y,pt[j*u+i+1].z-pt[j*u+i].z);
vb.set(pt[(j+1)*u+i].x-pt[j*u+i].x,pt[(j+1)*u+i].y-pt[j*u+i].y,pt[(j+1)*u+i].z-pt[j*u+i].z);
va.normalize();
vb.normalize();
norm[j*u+i].set(va.cross(vb));
norm[j*u+i].set(j*u+i);
}
va.set(pt[j*u+i].x-pt[j*u+i-1].x,pt[j*u+i].y-pt[j*u+i-1].y,pt[j*u+i].z-pt[j*u+i-1].z);
vb.set(pt[(j+1)*u+i].x-pt[j*u+i].x,pt[(j+1)*u+i].y-pt[j*u+i].y,pt[(j+1)*u+i].z-pt[j*u+i].z);
va.normalize();
vb.normalize();
norm[j*u+i].set(va.cross(vb));
norm[j*u+i].set(j*u+i);
}
for(i=0;i<u-1;i++)
{
va.set(pt[j*u+i+1].x-pt[j*u+i].x,pt[j*u+i+1].y-pt[j*u+i].y,pt[j*u+i+1].z-pt[j*u+i].z);
vb.set(pt[0*u+i].x-pt[j*u+i].x,pt[0*u+i].y-pt[j*u+i].y,pt[0*u+i].z-pt[j*u+i].z);
va.normalize();
vb.normalize();
norm[j*u+i].set(va.cross(vb));
norm[j*u+i].set(j*u+i);
}
va.set(pt[j*u+i].x-pt[j*u+i-1].x,pt[j*u+i].y-pt[j*u+i-1].y,pt[j*u+i].z-pt[j*u+i-1].z);
vb.set(pt[0*u+i].x-pt[j*u+i].x,pt[0*u+i].y-pt[j*u+i].y,pt[0*u+i].z-pt[j*u+i].z);
va.normalize();
vb.normalize();
norm[j*u+i].set(va.cross(vb));
norm[j*u+i].set(j*u+i);
}
/******************************旋转曲面生成面片*********************************/
void Revsurf::makefaces()
{
int i=0,j=0;
for(;j<v-1;j++)
{
for(i=0;i<u-1;i++)
{
face[j*(u-1)+i].nVerts=4;
face[j*(u-1)+i].vert=new VertexID[4];
face[j*(u-1)+i].vert[0].normIndex=j*u+i;
face[j*(u-1)+i].vert[1].normIndex=j*u+i+1;
face[j*(u-1)+i].vert[2].normIndex=(j+1)*u+i+1;
face[j*(u-1)+i].vert[3].normIndex=(j+1)*u+i;
face[j*(u-1)+i].vert[0].vertIndex=j*u+i;
face[j*(u-1)+i].vert[1].vertIndex=j*u+i+1;
face[j*(u-1)+i].vert[2].vertIndex=(j+1)*u+i+1;
face[j*(u-1)+i].vert[3].vertIndex=(j+1)*u+i;
}
}
for(i=0;i<u-1;i++)
{
face[j*(u-1)+i].nVerts=4;
face[j*(u-1)+i].vert=new VertexID[4];
face[j*(u-1)+i].vert[0].normIndex=j*u+i;
face[j*(u-1)+i].vert[1].normIndex=j*u+i+1;
face[j*(u-1)+i].vert[2].normIndex=0*u+i+1;
face[j*(u-1)+i].vert[3].normIndex=0*u+i;
face[j*(u-1)+i].vert[0].vertIndex=j*u+i;
face[j*(u-1)+i].vert[1].vertIndex=j*u+i+1;
face[j*(u-1)+i].vert[2].vertIndex=0*u+i+1;
face[j*(u-1)+i].vert[3].vertIndex=0*u+i;
}
}
void Revsurf::writeMesh(char *fname)
{
Mesh::writeMesh(face,norm,pt,numFaces,numNorms,numVerts,fname);
}
直纹面类:
class Rulesurf:public bspline,public Mesh //直纹面
{
public:
Rulesurf(Point3* pt1,Point3* pt2,int num,int uu,int vv,int mm); //构造函数
~Rulesurf(); //析构函数
public:
void writeMesh(char *fname); //将生成点、法线、面片 写入文件