在矩形上镶嵌六边形

Tessellating hexagons over a rectangle

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

我还有一个 视口 -- 一个矩形 canvas 我将在其中绘制六边形。

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

这张图片总结了我想做的事情:

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

一些其他信息:

设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)。使用相同的 ROWINC

绘制另一个水平行

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

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

你可以把矩形框想象成轴上的约束。

在图表中,水平线对应于 b,您的约束将采用 somenumber ≤ b 和 b ≤ somenumber 的形式。例如,矩形可能在 3 ≤ b ≤ 7 范围内。

垂直线有点棘手,但它们是对应于 r-g 的“对角线”。您的约束将采用 somenumber ≤ r-g 和 r-g ≤ somenumber 的形式。例如,它的范围可能是 -4 ≤ r-g ≤ 5。

现在你有两个带约束的轴,你可以形成一个循环。最简单的方法是让外循环使用 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 ≤ r-g 或 -4 ≤ 2*r-b 或 -4+b ≤ 2*r 或 (-4+b)/2 ≤ r 而不是 -4 ≤ r-g。同样,我们可以将 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 替换为矩形的实际边界。