半球形六角耕作 [英] Hexagonal tilling of hemi-sphere
问题描述
我需要在球形表面上有六角形网格.就像这里显示的一样.
I need to have hexagonal grid on a spherical surface. like shown here.
现在我正在做一个六角形的扁平网格. 并将其投影到半球的表面上.像这儿, 但是,正如您所看到的,有趣的伪像是边缘上的六边形比例过大.应该有一个更好的方法来使所有六边形的大小都几乎相等.
Right now I am doing a hexagonal flattened grid. and the projecting it onto the surface of a hemisphere. Like here, But as you can see, the funny artifact is hexagons on the edge are disproportionately large. There should be a better way to do this so that all the hexagons are near equal in their size.
我尝试了@spektre所建议的解决方案,但是我的代码正在生成以下图.
I had tried the solution like @spektre had suggested but my code was producing following plot.
我之所以使用a=sqrt(x*x+y*y)/r * (pi/2)
,是因为我想缩放从[0,r]
到z
[0,r]
的a
,所以角度a
的边界为[0,pi/2]
.
i was using the a=sqrt(x*x+y*y)/r * (pi/2)
because i wanted to scale a
that goes from [0,r]
to z
[0,r]
so angle a
has bounds of [0,pi/2]
.
但是只要使用a=sqrt(x*x+y*y)/r
,它就可以很好地工作.
But with just a=sqrt(x*x+y*y)/r
it works well.
新开发任务,新问题
我有一个问题,就是现在六边形在整个形状上都不相等.我希望它们在球顶和圆柱体上的形状均匀(区域明智).我对如何处理这个问题感到困惑?
I have the problem that now, the hexagons are not equal through out the shapes. I want a uniform shape (area wise) for them across the dome and cylinder. I am confused on how to manage this?
推荐答案
这里是我的主意:
-
在XY平面上创建平面六边形网格
网格的中心必须是我选择的球体的中心(0,0,0)
,并且网格的大小至少应为球体半径的2 *大.
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.
将平面坐标转换为球形
因此从(0,0,0)
到 XY 平面中的点坐标的距离是在球体表面上移动的弧长,因此,如果处理后的点是(x,y,z)
并且球体半径是r
,则球体上的纬度位置是:
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;
所以我们可以直接计算z坐标:
so we can directly compute z coordinate:
z=r*cos(a);
并将x,y
缩放到球体的表面:
and scale x,y
to surface of sphere:
a=r*sin(a)/sqrt(x*x+y*y);
x*=a; y*=a;
如果z
坐标为负,则您已经越过了半球,应该以不同的方式处理(跳过十六进制或转换为圆柱体或其他任何东西)
If the z
coordinate is negative then you have crossed half sphere and should handle differently (skip hex or convert to cylinder or whatever)
以下为 OpenGL/C ++ 示例:
//---------------------------------------------------------------------------
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();
}
//---------------------------------------------------------------------------
和用法:
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);
预览:
有关更多信息和想法,请参阅相关内容:
For more info and ideas see related:
- Make a sphere with equidistant vertices
- Turning a cylinder into a sphere without pinching at the poles
这篇关于半球形六角耕作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!