2

我有一个无限的六边形网格,由三次(xyz)坐标系定义,如下所示:

相互间隔 120 度的 3 条线,分别标记为 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
    
4

2 回答 2

2

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)

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

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

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

于 2015-10-22T05:46:13.617 回答
1

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

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

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

现在你有两个带有约束的轴,你可以形成一个循环。最简单的事情是使用外循环b

for (b = 3; b ≤ 7; b++) {
    …
}

内部循环有点棘手,因为那是对角线约束。由于我们知道 r+g+b=0,并且我们从外循环中知道 b 的值,我们可以重写 rg 上的二元约束。将 r+g+b=0 表示为 g=0-rb。现在代入 rg 并得到 r-(0-rb)。将 r-(0-rb) 简化为 2*rb。代替 -4 ≤ rg,我们可以说 -4 ≤ 2*rb 或 -4+b ≤ 2*r 或 (-4+b)/2 ≤ r。类似地,我们可以重新排列 rg ≤ 5 到 2*rb ≤ 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。

于 2016-07-20T17:53:33.580 回答