基于bSpline插值的直纹面和旋转曲面

该程序通过bSpline插值算法创建旋转曲面和直纹面,包括生成点、法线和面片。旋转曲面类(Revsurf)与直纹面类(Rulesurf)继承自bspline类,并实现相应的几何形状。程序通过视图界面进行交互,左侧视图更新参数,右侧视图实时绘制。视图间的通信由消息传递完成,当参数改变时,触发重绘以更新图形。
摘要由CSDN通过智能技术生成

此程序主要分为两部分,一部分是抽象旋转曲面和直纹面的类,另一部分是视图界面的类组织,二者通过在视图界面定义数据成员建立联系。

 

第一部分:

旋转曲面类:

 

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);                                  //将生成点、法线、面片 写入文件

#include <iostream> #include <cmath> #include <fstream> using namespace std; class scyt { float *x,*y,*d,*h,*u,*q,*a,*b,*c,*l,*r,*o,*M; int m; float y0,y3; public: scyt(); void qiudao(); void zgf(); void qiujie(); ~scyt(); }; void main() { scyt hello; hello.qiudao(); hello.zgf(); hello.qiujie(); } scyt::scyt() { ifstream fin("三次样条插值.txt"); for(float j;fin>>j;) { m=int(j); break; } x=new float[m]; y=new float[m]; d=new float[m]; h=new float[m-1]; u=new float[m-2]; q=new float[m-2]; a=new float[m-1]; b=new float[m]; c=new float[m-1]; l=new float[m]; r=new float[m-1];//此处的r为追赶法中的u; o=new float[m];//此处o为追赶法中的y M=new float[m];//此处M为追赶法中的x; int jishu=0; for(j;fin>>j;) { if(jishu<=m-1) x[jishu]=j; if(jishu>m-1&&jishu;<2*m) { y[jishu-m]=j; } if(jishu==2*m) { y0=j; } if(jishu==2*m+1) { y3=j; } jishu++; } fin.close(); } void scyt::qiudao() { for(int i=0;i<m-1;i++) { h[i]=x[i+1]-x[i]; } for(i=0;i<m-2;i++) { u[i]=h[i] / (h[i] + h[i+1]); } for(i=0;i<m-2;i++) { q[i]=1-u[i]; } d[0]=6/h[0]*((y[1]-y[0])/h[0]-y0); for(i=1;i<m-1;i++) { d[i]=6/(h[i-1]+h[i])*((y[i+1]-y[i])/h[i]-((y[i]-y[i-1])/h[i-1])); } d[m-1]=6/h[m-2]*(y3-(y[m-1]-y[m-2])/h[m-2]); } void scyt::zgf() { u[m-2]=1; for(int i=0;i<m;i++) { b[i]=2; } c[0]=1; for(i=1;i<m-1;i++) { c[i]=q[i-1]; } //........................................ l[0]=b[0]; for(i=0;i<m-1;i++) { r[i]=c[i] / l[i]; l[i+1]=b[i+1] - (u[i] * r[i]); } o[0]=d[0] / l[0]; for(i=1;i<m;i++) { o[i]=(d[i]-u[i-1]*o[i-1]) / l[i]; } M[m-1]=o[m-1]; for(i=m-2;i>=0;i--) { M[i]=o[i]-r[i] * M[i+1]; } cout<<m<<"个点的导数值分别是:"<<endl; for(i=0;i<m;i++) { cout<<"M"<<i+1<<"="; cout<<M[i]<<endl; } //M的值求出。。。。。。追赶法调用完毕 } void scyt::qiujie() { float S; for(;;) { float f; cout<<"请输入待求x的值(输入1000)时退出:"; cin>>f; if(f==1000) break; for(int i=0;i<m;i++) { if(f>x[i]&&f<x[i+1]) { S=pow((x[i+1]-f),3)*M[i]/(6*h[i]) + pow(f-x[i],3)*M[i+1]/(6*h[i]) + (x[i+1]-f)*(y[i]-h[i]*h[i]*M[i]/6)/h[i] + (f-x[i])*(y[i+1]-h[i]*h[i]*M[i+1]/6)/h[i]; cout<<"S["<<f<<"]="<<S<<endl; } } } } scyt::~scyt() { delete []x,y,d,h,u,q,a,b,c,l,r,o,M; }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值