Geometry 在矩形上细分六边形

Geometry 在矩形上细分六边形,geometry,hexagonal-tiles,tessellation,Geometry,Hexagonal Tiles,Tessellation,我有一个六边形的无限网格,由立方(x y z)坐标系定义,如下所示: 我还有一个视口——一个矩形画布,我将在其中绘制六边形 我的问题是这个。因为六边形的网格在各个方向上都是无限的,所以我不能一次画出所有的六边形。因此,我需要绘制视口中的所有六边形,并且只绘制这些六边形 此图总结了我想做的事情: 在此图像中,紫色六边形是我想要渲染的六边形,而白色六边形是我不想要渲染的六边形。黑色矩形是视口——所有与其相交的六边形都将被绘制如何找到要渲染的六边形(即其xyz坐标)? 其他一些信息: 我有一个函

我有一个六边形的无限网格,由立方(x y z)坐标系定义,如下所示:

我还有一个视口——一个矩形画布,我将在其中绘制六边形

我的问题是这个。因为六边形的网格在各个方向上都是无限的,所以我不能一次画出所有的六边形。因此,我需要绘制视口中的所有六边形,并且只绘制这些六边形

此图总结了我想做的事情:

在此图像中,紫色六边形是我想要渲染的六边形,而白色六边形是我不想要渲染的六边形。黑色矩形是视口——所有与其相交的六边形都将被绘制如何找到要渲染的六边形(即其xyz坐标)?

其他一些信息:

  • 我有一个函数,可以调用一个六边形平铺,并根据其立方xyz坐标在视口中的位置(x,y)居中绘制它。因此,我所需要的就是绘制每个矩形的xyz坐标,我可以绘制它们。这可能会简化问题
  • 我有从立方六边形坐标到x/y坐标的转换公式。给出上图,r/g/b为三次坐标轴,上图为x和y为笛卡尔坐标,s为六边形边的长度

    y = 3/2 * s * b
    b = 2/3 * y / s
    x = sqrt(3) * s * ( b/2 + r)
    x = - sqrt(3) * s * ( b/2 + g )
    r = (sqrt(3)/3 * x - y/3 ) / s
    g = -(sqrt(3)/3 * x + y/3 ) / s
    r + b + g = 0
    

让我们看X0,Y0是左上角的坐标,RectWidth是矩形宽度,HexWidth=s*Sqrt(3/2)是六边形宽度

找到最近六边形r0,g0,b0,HX0,HY0的中心。(矩形角位于该六边形中,因为六边形是Voronoy图单元格)。记住水平和垂直移位
DX=X0-HX0,DY=Y0-HY0

绘制水平行的Ceil(RectWidth/HexWidth)六边形,增加r坐标,减少f,保持b不变,
ROWINC=(1,-1,0)
注意如果
DY>HexWidth/2
,则需要额外的顶行,初始坐标上移
(r0,g0-1,b0+1)

如果
DX<0
,则按
L=(0,1,-1)
移动起始点,否则按
R=(1,0,-1)
移动起始点。用同一行绘制另一水平行

以替代方式移动行起始点(R后的L,L后的R)。绘制水平行,直到到达底部边缘


检查底部是否需要额外的行。

您可以根据轴上的约束来考虑矩形框

在图中,水平线对应于
b
,约束的形式为somenumber≤b和b≤一些数字。例如,矩形可能在3范围内≤b≤七,

垂直线有点复杂,但它们是对应于
r-g
的“对角线”。您的约束将采用somenumber形式≤r-g和r-g≤一些数字。例如,它的范围可能是-4≤r-g≤五,

现在有两个轴,它们上有约束,可以形成一个循环。最简单的方法是让外循环使用
b

for (b = 3; b ≤ 7; b++) {
    …
}
内部循环有点棘手,因为这是对角线约束。因为我们知道r+g+b=0,并且我们从外循环知道b的值,所以我们可以重写r-g上的双变量约束。将r+g+b=0表示为g=0-r-b。现在替换成r-g,得到r-(0-r-b)。将r-(0-r-b)简化为2*r-b。而不是-4≤我们可以说-4≤2*r-b或-4+b≤2*r或(-4+b)/2≤r。类似地,我们可以重新排列r-g≤5至2*r-b≤5对r≤(5+b)/2。这为我们提供了内部循环:

for (b = 3; b ≤ 7; b++) {
    for (r = (-4+b)/2; r ≤ (5+b)/2; r++) {
        g = 0-b-r;
        …
    }
}
最后一点是泛化,用矩形的实际边界替换常量3,7,-4,5