在矩形

时间:2015-10-22 00:21:59

标签: geometry hexagonal-tiles tessellation

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

3 lines at 120 degree intervals of each other, labeled x, y, and z, and a hexagonal honeycomb pattern using these axes.

我还有一个视口 - 一个矩形画布,我将绘制六边形。

我的问题是这个。因为六边形的网格在所有方向都是无限的,所以我无法一次性地绘制所有这些网格。因此,我需要绘制视口中的所有六边形,并且只绘制那些六边形。

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

Hexagons intersecting inside the rectangular viewport are colored purple and thus rendered, all other hexagons are not rendered and are colored white in the diagram

在这张图片中,紫色六边形是我想渲染的六边形,而白色六边形是我不想渲染的六边形。黑色矩形是hte视口 - 将绘制与其相交的所有六边形。 如何找到要渲染的六边形(IE的xyz坐标)?

其他一些信息:

  • 我有一个函数可以调用六边形瓷砖,并在视口中的位置(x,y)处绘制它,给定其立方xyz坐标。因此,我需要的是每个要绘制的矩形的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
    

2 个答案:

答案 0 :(得分: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 < 0,否则按R=(1, 0, -1)。使用相同的ROWINC

绘制另一个水平行

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

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

答案 1 :(得分:1)

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

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

垂直线有点棘手,但它们是“对角线”,对应r-g。你的约束形式有些数字≤r-g且r-g≤somenumber。例如,它可能是-4≤r-g≤5的范围。

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

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

内循环有点棘手,因为这是对角约束。既然我们知道r + g + b = 0,并且我们知道来自外循环的b的值,我们可以在r-g上重写双变量约束。当r = 0-r-b时,表达r + g + b = 0。现在替换为r-g并得到r-(0-r-b)。将r-(0-r-b)简化为2 * r-b。我们可以说-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替换为矩形的实际边界。