在路径规划、游戏设计栅格法应用中,正六边形网格不如矩形网格直接和常见,但是正六边形具有自身的应用特点,更适用于一些特殊场景中,比如旷阔的海洋、区域或者太空。本文主要讲述如何对正六边形进行几何学分析、网格化环境建模、坐标系转换以及正六边形间的关系求解等。六边形的具体代码实现可以参见github: https://github.com/wylloong/HexagonalGrids .
  几何学分析:正六边形的边长相等,内角都是120度,其它性质可以参见百度百科。在正六边形网格化布局设计中,典型的正六边形方向有水平方向(pointy topped,图1)和垂直方向(flat topped,图2)两类,两者性质类似。篇幅所限,本文主要讨论pointy topped类型的正六边形网格化布局。
图 1. pointy topped
图 2. flat topped
如图3所示的正六边形布局,针对pointy topped型的正六边形,设其边长为size,则六边形的宽width=sqrt(3)/2*size,和相邻六边形的水平距离hori=sqrt(3)/2*size,六边形的高是height=size*2,和相邻六边形的垂直距离是vert=1.5*size。

图 3. pointy topped型的正六边形几何示意图
  坐标系选择:假设实现六边形网格化,那么六边形位置关系的表达有很多方式,有Offset coordinates、Cube coordinates、Axial coordinates等。本文推荐使用Cube coordinates作为主要的展示方式,Axial coordinates作为网格存储单位和显示坐标系。
  Offset coordinates:最常用的坐标系,以左上角为坐标系原点,以横向为column轴,以纵向为roe轴,对行和列进行偏置。其中,针对flat topped型的正六边形,具有奇和偶两种表示方式,如下图所示。
  Cube coordinates:一种全新的看待正六边形的方式,它把正六边形看作具有三个轴,并且满足x+y+z=0的性质,并且我们可以使用标准的方法实现坐标系的加减乘除和求距离。Cube坐标系的原理和其它性质可以参见文献。
  因为我们已经有针对方形网格和cube网格的计算方法,使用cube坐标系允许我们对六边形采用这些算法。当这个算法要和其他坐标系交互时,我会把其他坐标系转换为cube坐标系,然后计算结束后在转换为其他坐标系。
  Axial coordinates:该坐标系是由cube坐标系中三个轴中的两个组成的。因为在cube坐标系有x+y+z=0的限制,所以第三个轴是多余的。Axial coordinates主要应用于地图存储和对用户的显示。Axial coordinates相比offset grids的优点是坐标系更清楚,劣势是当存储一个长方形地图时显得有点怪异。
  总结:Offset coordinates因为符合square grids通用的笛卡尔坐标系,是我们最容易想到的坐标系,但是因为两轴中的一轴必须跟随变化,是一件复杂的事情;Cube and axial systems随着增长而变化并且具有相对简单的计算方法,但是在存储时具有一定的复杂度。

  Coordinate conversion:我们通常在项目中使用axial or offset coordinates,但是很多算法使用cube坐标系更容易去表达,所以我们需要在坐标系之间转换。
  Axial coordinates和cube coordinates联系紧密,所以转换公式相对简单。

  Offset coordinates和cube coordinates转换有点复杂。本文主要针对even-q offset和odd-q offset进行研究。
  邻近网格:cube coordinates容易求出相邻的6个邻近正六边形网格,但是offset坐标系却比较复杂。
  Cube coordinates:在正六边形上移动一个网格,涉及到改变cube坐标系中两个轴,一个+1,另一个-1,所以共有六种可能性,每一种可能性对应于六边形的一个方向。

  Axial coordinates:如前所示,我们以cube为起点,由cube转换为axil坐标系即可,如下图所示。
  Distance: 在cube坐标系中,每一个六边形是一个在cube里面的3d空间。在六边形中相邻的六边形距离是1,但是在cube grid里面距离是2,这会让距离求解变得简单和快速。在square grid中,Manhattan distances are abs(dx) + abs(dy). In a cube grid, Manhattan distances are abs(dx) + abs(dy) + abs(dz).
所以,在cube坐标系中,距离可以表示为

  在Axial coordinates,第三个坐标系是缺省的,所以通用的做法是先转变为cube坐标系,再求距离。
  在offset坐标系中,正如Axial coordinates坐标系,我们把offset转变为cube坐标系再求取距离。
  路径规划:如果使用基于图论的A*或者Dijkstra算法,在六边形中寻找最短路径和正方形网格并没有太多不同。其中,不同的是邻近网格位置获取方法不同,需要用到前面的方法获取临近网格。
  启发函数:A*算法使用heuristic功能求出两个位置的距离。可以使用距离公式求出距离,乘以移动代价。
  参考文献和资料:
1、http://www.redblobgames.com/grids/hexagons/
2、Her I. Geometric transformations on the hexagonal grid[J]. IEEE Transactions on Image Processing A Publication of the IEEE Signal Processing Society, 1995, 4(9):1213-22.

转载于:https://www.cnblogs.com/DHUtoBUAA/p/7192315.html

正六边形网格化(Hexagonal Grids)原理与实现相关推荐

  1. 游戏场景offset坐标系关联正六边形cube坐标系

            MMO中,游戏场景即游戏地图,服务器要做的就是将地图上所有的玩家信息同步.为了减轻服务器压力,根据游戏本身的设定,如能见度,服务器只需根据不同的玩家返回相应的数据即可.         ...

  2. html中怎么写正六边形,用css画正六边形的方法

    用css画正六边形的方法 发布时间:2020-09-14 14:56:11 来源:亿速云 阅读:80 作者:小新 小编给大家分享一下用css画正六边形的方法,希望大家阅读完这篇文章后大所收获,下面让我 ...

  3. html如何将图片做成六边形,css画正六边形的两种方法

    说下两种css 制作正六边形的方法. 先看一下结果: 在之前要先了解一下正六边形内角和边的关系,正六边形的每个内角是60deg,如图(√3其实是根号3): 方法一:原理把正六边形分成三部分,左中右分别 ...

  4. html中怎么写正六边形,如何用css画正六边形?用css画正六边形的两种方法(代码实例)...

    本章给大家介绍如何用css画正六边形?用css画正六边形的两种方法(代码实例).有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在之前要先了解一下正六边形内角和边的关系,正六边形的每个 ...

  5. css实现图片背景填充的正六边形

    最近有个需求需要实现带有图片背景的正六边形,这里记录一下我自己实现的方法. 我项目里的最终效果大概是这样子的,这里我们只演示实现一个正六边形. 六边形的实现原理其实就是通过旋转三个重叠的矩形得到的,如 ...

  6. 二维平面坐标系中,判断某点是否在正六边形内 | python 实现 + 数学推导(已知正六边形六个顶点坐标)

    参考:高效判断点是否在正六边形蜂窝内的方法 上述文章给了我们一个高效的思路:在正六边形为原点且中心轴与y轴重合时,如何高效判断点是否在该正六边形内.本文的工作是将这种情况推广到正六边形处于任意位置. ...

  7. 【matlab】画正六边形、矩形、圆形点阵

    矩形 clc;clear; %%正方形排列 n=22;%为奇数,表示几x几的矩阵 a=zeros(n,n,2);%初始化 for i=1:nfor j=1:na(i,j,1)=-4.5*((n-1)/ ...

  8. Matlab代码生成任意边长等间距正六边形采样点

    Matlab代码生成任意边长等间距正六边形采样点 https://blog.csdn.net/Hanghang_/article/details/87064184 本文以n代表正六边形在x轴正轴上的长 ...

  9. 正六边形:判断点是否在正六边形内

    前文 正六边形:平铺中函数 //根据坐标计算网格信息 Vec2 HelloWorld::getGridByPos(const Vec2& pos) {int girdX = pos.x/ (1 ...

  10. 实现正六边形、圆形及带倒角正六边形的头像显示

    从网上下的一个圆形头像demo,然后在上面的基础上实现了自己的正六边形及带倒角的正六边形. 废话不多说,直接上代码 import android.content.Context; import and ...

最新文章

  1. Bind和Eval的区别详解
  2. 技术方案包括哪些内容_揭秘:网络营销推广方案的内容包括哪些?
  3. Microsoft CRM 3.0 Mobile安装手记(二)——Server端安装
  4. [转]Eclipse插件开发之基础篇(2) 第一个Eclipse插件
  5. Hadoop框架:单服务下伪分布式集群搭建
  6. quartz SpringMvc 动态定时任务(quartz2.2)
  7. python代码转换为pytorch_python基础教程Pytorch之Tensor和Numpy之间的转换的实现方法...
  8. esri-leaflet入门教程(5)- 动态绘制图形
  9. 在flex3中调用js函数
  10. Structs2 总结
  11. 51单片机之串口通信详解及代码示例
  12. JS继承--圣杯模式的详解
  13. 2015年7月深圳社保缴费基数费率表
  14. 统计分布——常用且重要的三种分布
  15. 【2020-07】字节跳动面试凉经(年轻人的第一场 技术面试)
  16. TensorFlow报错:AttributeError: module 'tensorflow._api.v1.train' has no attribute 'SummaryWriter'等
  17. V2X-Hub,车路协同云控平台
  18. java ocx调用_Java调用ocx控件以及dll
  19. 国际八大传感器生产厂家排名
  20. 未来十年 计算机人才缺口大吗,未来十年 国内人才最紧缺的是这六大专业

热门文章

  1. [渝粤教育] 西南科技大学 英语语法2 在线考试复习资料
  2. 【sklearn第十七讲】特征选择
  3. 23种设计模式(十六)接口隔离之中介者
  4. Understand-4.0.877-Linux-64bit.tgz最新版本2017年源代码阅读利器,养眼theme之配置
  5. python_内置字符串
  6. [Android] Android 任务栈 【转载】
  7. Python 使用pyinstaller将py文件发布成exe程序
  8. 软硬负载之间的对比及优缺点
  9. Java问题解决:错误: 找不到或无法加载主类
  10. msp430入门编程07