Hexagonal tilling of hemi-sphere

不问归期 提交于 2019-12-02 04:05:07
Spektre

Here is what I have in mind:

  1. create planar hex grid on XY plane

    center of your grid must be the center of your sphere I chose (0,0,0) and size of the grid should be at least the 2*radius of your sphere big.

  2. convert planar coordinates to spherical

    so distance from (0,0,0) to point coordinate in XY plane is arclength traveling on surface of your sphere so if processed point is (x,y,z) and sphere radius is r then latitude position on sphere is:

    a=sqrt(x*x+y*y)/r;
    

    so we can directly compute z coordinate:

    z=r*cos(a);
    

    and scale x,y to surface of sphere:

    a=r*sin(a)/sqrt(x*x+y*y);
    x*=a; y*=a;
    

    If the z coordinate is negative then you have crossed half sphere and should handle differently (skip hex or convert to cylinder or whatever)

Here Small OpenGL/C++ example for this:

//---------------------------------------------------------------------------
const int _gx=15;           // hex grid size
const int _gy=15;
const int _hy=(_gy+1)<<1;   // hex points size
const int _hx=(_gx+1);
double hex[_hy][_hx][3];    // hex grid points
//---------------------------------------------------------------------------
void hexgrid_init(double r) // set hex[][][] to planar hex grid points at xy plane
    {
    double x0,y0,x,y,z,dx,dy,dz;
    double sx,sy,sz;
    int i,j;
    // hex sizes
    sz=sqrt(8.0)*r/double(_hy);
    sx=sz*cos(60.0*deg);
    sy=sz*sin(60.0*deg);

    // center points arrounf (0,0)
    x0=(0.5*sz)-double(_hy/4)*(sz+sx);
    y0=-double(_hx)*(sy);
    if (int(_gx&1)==0) x0-=sz+sx;
    if (int(_gy&1)==0) y0-=sy; else y0+=sy;

    for (y=y0,i=0;i<_hy;i+=2,y+=sy+sy)
     for (x=x0,j=0;j<_hx;j++,x+=sz)
        {
        hex[i][j][0]=x;
        hex[i][j][1]=y;
        hex[i][j][2]=0.0;
        x+=sz+sx+sx; j++; if (j>=_hx) break;
        hex[i][j][0]=x;
        hex[i][j][1]=y;
        hex[i][j][2]=0.0;
        }

    for (y=y0+sy,i=1;i<_hy;i+=2,y+=sy+sy)
     for (x=x0+sx,j=0;j<_hx;j++,x+=sx+sx+sz)
        {
        hex[i][j][0]=x;
        hex[i][j][1]=y;
        hex[i][j][2]=0.0;
        x+=sz; j++; if (j>=_hx) break;
        hex[i][j][0]=x;
        hex[i][j][1]=y;
        hex[i][j][2]=0.0;
        }

    }
//---------------------------------------------------------------------------
void hexgrid_half_sphere(double r0) // convert planar hex grid to half sphere at (0,0,0) with radius r0
    {
    int i,j;
    double x,y,z,a,l;
    for (i=0;i<_hy;i++)
     for (j=0;j<_hx;j++)
        {
        x=hex[i][j][0];
        y=hex[i][j][1];
        z=hex[i][j][2];
        l=sqrt(x*x+y*y);    // distance from center on xy plane (arclength)
        a=l/r0;             // convert arclength to angle
        z=r0*cos(a);        // compute z coordinate (sphere)
        if (z>=0.0)         // half sphere
            {
            a=r0*sin(a)/l;
            }
        else{               // turn hexes above half sphere to cylinder
            z=0.5*pi*r0-l;
            a=r0/l;
            }
        x*=a;
        y*=a;
        hex[i][j][0]=x;
        hex[i][j][1]=y;
        hex[i][j][2]=z;
        }
    }
//---------------------------------------------------------------------------
void hex_draw(int x,int y,GLuint style)     // draw hex x = <0,_gx) , y = <0,_gy)
    {
    y<<=1;
    if ((x&1)==0) y++;
    if ((x<0)||(x+1>=_hx)) return;
    if ((y<0)||(y+2>=_hy)) return;
    glBegin(style);
    glVertex3dv(hex[y+1][x  ]);
    glVertex3dv(hex[y  ][x  ]);
    glVertex3dv(hex[y  ][x+1]);
    glVertex3dv(hex[y+1][x+1]);
    glVertex3dv(hex[y+2][x+1]);
    glVertex3dv(hex[y+2][x  ]);
    glEnd();
    }
//---------------------------------------------------------------------------

And usage:

hexgrid_init(1.5);
hexgrid_half_sphere(1.0);

int x,y;
glColor3f(0.0,0.2,0.3);
for (y=0;y<_gy;y++)
 for (x=0;x<_gx;x++)
  hex_draw(x,y,GL_POLYGON);
glLineWidth(2);
glColor3f(1.0,1.0,1.0);
for (y=0;y<_gy;y++)
 for (x=0;x<_gx;x++)
  hex_draw(x,y,GL_LINE_LOOP);
glLineWidth(1);

And preview:

For more info and ideas see related:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!