有一个六边形网格。绘制它不是问题,但还有另一个任务要做。用户戳到某处,要求计算行列号。方形嵌套网格没有问题:我们将光标坐标与网格角度之间的差值除以字段大小,商的整数部分是行号。但是六边形网格有两个特点。
- 奇数行向右移动内切圆的半径。先计算行号,再计算列号,计算列号时要考虑偶数行和奇数行左边界横坐标的差异。
- 相邻行的字段在y轴上的投影部分重叠,即从第一行开始,任何一行字段的上部嵌入前一行字段的下部之间,并且直到倒数第二行的任何行的字段的下部嵌入在下一行字段的上部之间。如何考虑?
我也不想遍历命中测试中的所有字段。你能建议更快的东西吗?不是最好的变体,而是更快的字段枚举。只用索引填充屏幕外缓冲区?或者还有其他选择吗?如果网格旋转 45° 会怎样?
你不需要搜索,你可以计算 - 它比矩形网格更复杂,但不是根本。
首先,通过将顶行的 Y 坐标(从顶部顶点开始计算)除以 来计算“行”
3/2*a,其中 a 是六边形的边。事实证明,条带捕获了顶行的三角形,但当前行的底部三角形没有。如果该行结果为偶数(从零开始计数),则 X 没有移动,否则等于
a*sqrt(3)/2.我们从真实的 X 坐标中减去偏移量,将结果除以
a*sqrt(3),我们找到“列”。我们得到了单元格的临时坐标。现在我们确定点相对于单元格的相对坐标。如果点真的落在这个单元格中,那么工作就完成了。如果它高于上边缘,那么我们校正坐标 - 该点属于左上角或右上角的单元格(对于顶行 - 它可能在字段之外)
详细信息取决于您选择的编号系统(有很多,包括具有三个坐标的编号系统)。此处关于六角格子的出色工作。
这是另一个(平顶)布局的示例
Delphi代码,这里单元格的基点是圆心,先计算列,再计算行,当单元格超出边界时进行修正(点在右边直线的右边) -上边缘或右下边缘直线的右侧。带绘图的完整代码在这里