把一个圆柱体变成一个球体而不会夹住两极

我正在努力生成一个由六边形网格制成的星球。 两极是不需要的 – 使这一点更容易。 有没有更好的方法把圆柱体变成一个六angular形或三angular形的球体?

这是所需的步骤:

  1. 生成一个六边形的2D平面(ok)
  2. 把飞机变成一个气缸(好)
  3. 把油缸变成球体/地圈(种类)

对于第二步,我只是使用Sin和Cos将顶点移动到圆形。 对于第3步,现在我只是使用: vertices[i] = vertices[i].normalized * radius;

图像可视化的问题,因为它是目前。

请注意,杆是有意切断的。 红色的部分显示了一个六边形网格的外观。 我将不得不保持大致相同的大小和方向,因为它们被用于游戏和视觉元素。 每个hex都有一个邻居列表,基本上就像一个图。

我将做一个球体三angular测量,而不是圆柱体到球体的映射。

  1. 我会先从2个六边形开始

    每个在极点开始,在赤道上结束,或者只完成一半,并在完成时reflection另一个。

  2. 然后recursion地细分三angular形

    所以将线分成一半,改变中点坐标与球面alignment。 这将创build三angular形球体。 细分为有效的点数以形成六边形并具有足够的网格点。

  3. 将六angular形中点坐标更改回六angular形平面

    所以采取另一个6点,并计算平均坐标,让你点中间…

像这样的东西:

hexagonation

为更多的想法看这里:

  • 球体上密度最高的位置
  • 用等距顶点制作一个球体

三angular测量(无六angular校正)

 //--------------------------------------------------------------------------- #include <math.h> #include "list.h" class mesh { public: class _pnt { public: double p[3]; _pnt(){}; _pnt(_pnt& a){ *this=a; }; ~_pnt(){}; _pnt* operator = (const _pnt *a) { *this=*a; return this; }; /*_pnt* operator = (const _pnt &a) { ...copy... return this; };*/ }; class _fac { public: int i0,i1,i2; _fac(){}; _fac(_fac& a){ *this=a; }; ~_fac(){}; _fac* operator = (const _fac *a) { *this=*a; return this; }; /*_fac* operator = (const _fac &a) { ...copy... return this; };*/ }; List<_pnt> pnt; // mesh points List<_fac> fac; // mesh triangles mesh() {} mesh(mesh& a) { *this=a; } ~mesh() {} mesh* operator = (const mesh *a) { *this=*a; return this; } //mesh* operator = (const mesh &a) { ...copy... return this; } void draw(); // draws the mesh with OpenGL void sphere(int n); // init mesh with unit sphere from triangles (n recursion layers) }; //--------------------------------------------------------------------------- void mesh::draw() { int i; _fac *f; // fill glColor3f(0.7,0.7,0.7); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glDepthFunc(GL_LEQUAL); glBegin(GL_TRIANGLES); for (i=0,f=fac.dat;i<fac.num;i++,f++) { glVertex3dv(pnt.dat[f->i0].p); glVertex3dv(pnt.dat[f->i1].p); glVertex3dv(pnt.dat[f->i2].p); } glEnd(); // wireframe glColor3f(0.1,0.3,0.7); glLineWidth(2.0); for (i=0,f=fac.dat;i<fac.num;i++,f++) { glBegin(GL_LINE_LOOP); glVertex3dv(pnt.dat[f->i0].p); glVertex3dv(pnt.dat[f->i1].p); glVertex3dv(pnt.dat[f->i2].p); glEnd(); } glLineWidth(1.0); } //--------------------------------------------------------------------------- void mesh::sphere(int n) { // init 2 hexagons int i,j,m,i0,i1,i2,j0,j1,j2; double a,da=M_PI/3.0; double *p0,*p1; _pnt p; _fac f,*g; pp[0]= 0.0; pp[1]= 0.0; pp[2]=+1.0; pnt.add(p); pp[2]=-1.0; pnt.add(p); for (i=0,a=0.0;i<6;i++,a+=da) { pp[0]=cos(a); pp[1]=sin(a); pp[2]= 0.0; pnt.add(p); } // top half f.i0=0; f.i1=2; f.i2=3; fac.add(f); f.i0=0; f.i1=3; f.i2=4; fac.add(f); f.i0=0; f.i1=4; f.i2=5; fac.add(f); f.i0=0; f.i1=5; f.i2=6; fac.add(f); f.i0=0; f.i1=6; f.i2=7; fac.add(f); f.i0=0; f.i1=7; f.i2=2; fac.add(f); // botom half f.i0=1; f.i1=3; f.i2=2; fac.add(f); f.i0=1; f.i1=4; f.i2=3; fac.add(f); f.i0=1; f.i1=5; f.i2=4; fac.add(f); f.i0=1; f.i1=6; f.i2=5; fac.add(f); f.i0=1; f.i1=7; f.i2=6; fac.add(f); f.i0=1; f.i1=2; f.i2=7; fac.add(f); // subdivide triangles for (;n>0;n--) // recursion layers for (m=fac.num,i=0;i<m;i++)// scan through all original faces { g=&fac[i]; // point indexes i0=g->i0; j0=pnt.num; // i0 i1=g->i1; j1=j0+1; // j0 j2 i2=g->i2; j2=j0+2; // i1 j1 i2 // genere mid points + sphere surface correction distance from (0,0,0) must be 1.0 (radius) for (j=0;j<3;j++) pp[j]=0.5*(pnt[i0].p[j]+pnt[i1].p[j]); a=1.0/sqrt((pp[0]*pp[0])+(pp[1]*pp[1])+(pp[2]*pp[2])); for (j=0;j<3;j++) pp[j]*=a; pnt.add(p); for (j=0;j<3;j++) pp[j]=0.5*(pnt[i1].p[j]+pnt[i2].p[j]); a=1.0/sqrt((pp[0]*pp[0])+(pp[1]*pp[1])+(pp[2]*pp[2])); for (j=0;j<3;j++) pp[j]*=a; pnt.add(p); for (j=0;j<3;j++) pp[j]=0.5*(pnt[i2].p[j]+pnt[i0].p[j]); a=1.0/sqrt((pp[0]*pp[0])+(pp[1]*pp[1])+(pp[2]*pp[2])); for (j=0;j<3;j++) pp[j]*=a; pnt.add(p); // change original fac g->i0=j0; g->i1=j1; g->i2=j2; // add 3 x fac f.i0=i0; f.i1=j0; f.i2=j2; fac.add(f); f.i0=j0; f.i1=i1; f.i2=j1; fac.add(f); f.i0=j2; f.i1=j1; f.i2=i2; fac.add(f); } } //--------------------------------------------------------------------------- 

有点好奇,所以我试图编码这个用法很简单:

 mesh obj; // somewhere global... obj.sphere(3); // init (call once or on change of n...) obj.draw(); // inside your gl draw scene routine/event... 

所以这里是结果概述

结果

顶部和底部的杆子看起来不错,沿赤道有一些变形,但部分也可能由鱼眼引起。 如果初始形状靠近想要的结果起始几何体进给,则可能有更好的结果