细分球代码 (参考opengl redbook 的第二章)

从四面体细分生成一个球网格的小代码。 参考opengl redbook 的第二章。
745x264

#include <cstdio>
#include <cmath>
#include <fstream>
#include <iostream>
using std::ofstream;

typedef  float FLOAT;
struct Point3{
FLOAT c[3];
FLOAT& operator[](int i) { return c[i]; }
const FLOAT operator[](int i) const { return c[i]; }
};
struct Triangle3{
int t[3];
int& operator[](int i) { return t[i]; }
const int operator[](int i) const { return t[i]; }
};

void normalize(Point3 &v){
   FLOAT d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); 
   if (d == 0.0) {
      printf("zero length vector\n");    
      return;
   }
   v[0] /= d; v[1] /= d; v[2] /= d; 
}


#include <vector>
using std::vector;
vector<Point3> points;
vector<Triangle3> triangles;

vector<Point3> points_old;
vector<Triangle3> triangles_old;

int insert(const Point3 &v,vector<Point3> &points){
Point3 P;
FLOAT error;
for(int i = 0 ; i<points.size();i++){
P = points[i];
error = sqrt((P[0]-v[0])*(P[0]-v[0])+(P[1]-v[1])*(P[1]-v[1])
+(P[2]-v[2])*(P[2]-v[2]));
if(error<1e-5)
return i;
}
points.push_back(v);
return points.size()-1;

}
void genTriangle(Point3 &v1, Point3 &v2, Point3 &v3){
int i = insert(v1,points);
int j = insert(v2,points);
int k = insert(v3,points);
Triangle3 T;
T[0] = i; T[1] = j; T[2] = k;
triangles.push_back(T);
}

void subdivide(Point3 &v1, Point3 &v2, Point3 &v3) 
   Point3 v12, v23, v31;   
 //  FLOAT v12[3], v23[3], v31[3];    
   int i;

   for (i = 0; i < 3; i++) { 
      v12[i] = v1[i]+v2[i]; 
      v23[i] = v2[i]+v3[i];     
      v31[i] = v3[i]+v1[i];    
   } 
   normalize(v12);    
   normalize(v23); 
   normalize(v31); 
   genTriangle(v1, v12, v31);    
   genTriangle(v2, v23, v12);    
   genTriangle(v3, v31, v23);    
   genTriangle(v12, v23, v31); 
}

void copy(const vector<Point3> &points,vector<Point3> &dst_points){
dst_points.clear();
for(int i = 0 ; i<points.size();i++){
dst_points.push_back(points[i]);
}
}
void copy(const vector<Triangle3> &triangles,vector<Triangle3> &dst_triangles){
dst_triangles.clear();
for(int i = 0 ; i<triangles.size();i++){
dst_triangles.push_back(triangles[i]);
}
}

//#define OFF_FORMAT
void genSphere(){
Point3 P;
Triangle3 T;
P[0] = 1; P[1] =  0; P[2] =  0;
points.push_back(P);
P[0] = -1; P[1] =  0; P[2] =  0;
points.push_back(P);
P[0] = 0; P[1] =  1; P[2] =  0;
points.push_back(P);
P[0] = 0; P[1] =  -1; P[2] =  0;
points.push_back(P);
P[0] = 0; P[1] =  0; P[2] =  1;
points.push_back(P);
P[0] = 0; P[1] =  0; P[2] =  -1;
points.push_back(P);

T[0] = 0; T[1] =  4; T[2] =  2;
triangles.push_back(T);
T[0] = 2; T[1] =  4; T[2] =  1;
triangles.push_back(T);
T[0] = 1; T[1] =  4; T[2] =  3;
triangles.push_back(T);
T[0] = 3; T[1] =  4; T[2] =  0;
triangles.push_back(T);
T[0] = 0; T[1] =  2; T[2] =  5;
triangles.push_back(T);
T[0] = 2; T[1] =  1; T[2] =  5;
triangles.push_back(T);
T[0] = 1; T[1] =  3; T[2] =  5;
triangles.push_back(T);
T[0] = 3; T[1] =  0; T[2] =  5;
triangles.push_back(T);


Point3 v1,v2,v3;
int level = 6;
for(int l = 0 ; l<level;l++){
copy(points,points_old);
copy(triangles,triangles_old);
triangles.clear();
for(int j =0; j<triangles_old.size();j++){
T[0] = triangles_old[j][0];
T[1] = triangles_old[j][1];
T[2] = triangles_old[j][2];
v1 = points_old[T[0]];
v2 = points_old[T[1]];
v3 = points_old[T[2]];
subdivide(v1,v2,v3);
}
std::cout<<"vertices: "<<points.size()<<"  triangles: "<<triangles.size()<<std::endl;
}


//output
std::cout<<"start to write to sphere.txt...\n";
#ifdef OFF_FORMAT
ofstream oF("sphere.off");
if(!oF) return;
oF<<"OFF\n";
oF<<points.size()<<" "<<triangles.size()<<" 0\n";
#else
ofstream oF("sphere.txt");
if(!oF) return;
oF<<points.size()<<" "<<triangles.size()<<"\n";
#endif
for(int i = 0 ; i<points.size();i++)
oF<<points[i][0]<<" "<<points[i][1]<<" "<<points[i][2]<<"\n";

for(int i = 0 ; i<triangles.size();i++)
#ifdef OFF_FORMAT
oF<<"3 "<<triangles[i][0]<<" "<<triangles[i][1]<<" "<<triangles[i][2]<<"\n";
#else
oF<<triangles[i][0]<<" "<<triangles[i][1]<<" "<<triangles[i][2]<<"\n";
#endif
oF.close();
std::cout<<"finished writing!\n";

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值