如何遍历六边形网格指定圆心与半径的圆形区域单元格
点顶偏移六边形网格圆形区域遍历方案
你用的是Unity默认点顶朝上的六边形网格,采用奇数行右偏移的Offset索引规则,和你给出的半径1测试用例完全匹配。不需要复杂的范围推导,用两层循环就能搞定,逻辑简单不容易写错,遍历顺序不影响结果。
实现思路
- 先圈出六边形的外接矩形:x轴范围是
中心x - 半径到中心x + 半径,y轴范围是中心y - 半径到中心y + 半径,两层循环直接扫完这个矩形里的所有格子 - 对每个格子,把偏移坐标转成六边形常用的轴向坐标,用整数运算算和中心的六边形距离,距离小于等于半径的就是目标区域内的格子
- 整个计算没有浮点运算,性能开销极低,哪怕半径很大也不会有性能问题
可直接复用的代码
// 入参:中心单元格坐标(cx, cy),遍历半径radius(radius=0仅返回中心,完全匹配你给出的半径计数规则) void GetHexCellsInCircle(int cx, int cy, int radius) { // 外层遍历所有行 for (int y = cy - radius; y <= cy + radius; y++) { // 内层遍历所有列 for (int x = cx - radius; x <= cx + radius; x++) { // 偏移坐标转轴向坐标,位运算y&1可替换为y%2,效果一致 int curAq = x - (y - (y & 1)) / 2; int curAr = y; int centerAq = cx - (cy - (cy & 1)) / 2; int centerAr = cy; // 计算六边形网格距离(无浮点运算) int dq = curAq - centerAq; int dr = curAr - centerAr; int hexDist = (Math.Abs(dq) + Math.Abs(dq + dr) + Math.Abs(dr)) / 2; if (hexDist <= radius) { // 这里拿到的(x,y)就是符合要求的单元格坐标,直接写处理逻辑即可 Debug.Log($"({x}, {y})"); } } } }
正确性校验
代入你给的测试case:中心(3,3),半径1
- 遍历y范围2、3、4,x范围2、3、4
- 最终输出的坐标为
(3, 3), (4, 4), (4, 3), (4, 2), (3, 2), (2, 3), (3, 4),和你给出的预期列表完全一致,无遗漏无多余。
要是后续换用偶数行偏移、平顶朝向的六边形,只需要修改偏移坐标转轴向坐标的公式即可,整体两层循环的框架完全不用动。
内容的提问来源于stack exchange,提问作者muell
相关产品推荐
相关产品推荐

