在路径规划、游戏设计栅格法应用中,正六边形网格不如矩形网格直接和常见,但是正六边形具有自身的应用特点,更适用于一些特殊场景中,比如旷阔的海洋、区域或者太空。本文主要讲述如何对正六边形进行几何学分析、网格化环境建模、坐标系转换以及正六边形间的关系求解等。六边形的具体代码实现可以参见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功能求出两个位置的距离。可以使用距离公式求出距离,乘以移动代价。
 
  参考文献和资料:
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.
 

正六边形网格化(Hexagonal Grids)原理与实现的更多相关文章

  1. Unity3D 正六边形,环状扩散,紧密分布,的程序

    最近在做一个正六边形的游戏,被一开始的布局难倒了. 需求:中心有个正六边形,输入围绕中心扩散的环数,自动创建和摆放. 大概就是这样的吧,我觉得这个非常轻松的就可以搞定了.啊~~~~~啊~~~ 五环~~ ...

  2. css3--布局正六边形

    怎样布局正六边形?-->如果不能直接布局,就只能采用图形的组合.-->既然是正六边形,则: -->AB=2分之根号3乘2倍的边长,也就是对于矩形ABCD来说,AB是BD的根号3倍(也 ...

  3. 正态QQ图的原理

    code{white-space: pre;} pre:not([class]) { background-color: white; }if (window.hljs && docu ...

  4. ArcGIS中实现指定面积蜂窝(正六边形)方法

    本篇博文为博主(whgiser)原创,转载请注明. 空间聚集研究中,地理尺度大多数都是基于格网构建的,只需fishnet下就行了.也常有使用社区.交通小区(TZ)作为研究单元的.直到发现蜂窝网络做出的 ...

  5. #使用Python的turtle绘制正六边形、叠边形

    1.#Python的turtle绘制正六边形 代码: len=100 #表示边长像素 import turtle as t #正六边形内角都是120度,外角60度 for i in range(6): ...

  6. 第五课 Css3旋转放大属性,正六边形的绘制

    ---恢复内容开始--- 一.效果 二.知识点 1.background-color: rgba(0,0,0,.4);   (红色.绿色.蓝色.透明度(0-1)) 2.position: absolu ...

  7. Design and Implementation of Global Path Planning System for Unmanned Surface Vehicle among Multiple Task Points

    Design and Implementation of Global Path Planning System for Unmanned Surface Vehicle among Multiple ...

  8. css实现六边形图片(最简单易懂方法实现高逼格图片展示)

    不说别的,先上效果: 用简单的div配合伪元素,即可‘画出’这幅六边形图片,原理是三个相同宽高的div,通过定位旋转拼合成一个六边形,再利用背景图层叠,形成视觉上的一张整图.下面咱们一步一步来实现. ...

  9. Android 正 N 边形圆角头像的实现

    卖一下广告,欢迎大家关注我的微信公众号,扫一扫下方二维码或搜索微信号 stormjun94(徐公码字),即可关注. 目前专注于 Android 开发,主要分享 Android开发相关知识和一些相关的优 ...

随机推荐

  1. 在控制台显示“Hello World”

    //作者:江骆 //功能:在控制台显示"Hello World" //日期:2017.7.19 public class helloworld   //public 表示公共类,一 ...

  2. java:数组操作工具类 java.util.Arrays包 主要方法详解

    Arrays类位于Java.util包下,是一个对数组操作的工具类,现将Arrays类中的方法做一个总结(JDK版本:1.6.0_34).Arrays类中的方法可以分为八类: sort(对数组排序) ...

  3. linux防火墙简单的使用

    Centos升级到7之后,内置的防火墙已经从iptables变成了firewalld.所以,端口的开启还是要从两种情况来说明的,那就是iptables和firewalld.本文章参考官网教程基础 一. ...

  4. Activiti-06-.事件

    Events 事件 1, 事件用于对发生在流程生命周期的事情进行建模.事件总是被形象成一个圆圈.在BPMN 2.0 中,存在两种主要的事件类型:捕获事件和抛出事件. 捕获:流程执行到该事件时,会等待 ...

  5. java线程池相关知识点总结

    Android中常见到的很多通用组件一般都离不开"池"的概念,如各种图片加载库,网络请求库,即使Android的消息传递机制中的Meaasge当使用Meaasge.obtain() ...

  6. 高德地图markers生成和点击

    因为自己平时上班也是比较忙,遇到什么写什么,希望能给现在的你一些帮助,都是自己在工作中遇到的问题,给自己一个提醒,也是分享 相信很多人在做高德地图开发的时候,对于新手,官方的demo解读单个marke ...

  7. 笔记|《简明Python教程》:编程小白的第一本python入门书

    <简明Python教程>这本书是初级的Python入门教材,初级内容基本覆盖,对高级内容没有做深入纠结.适合刚接触Python的新手,行文比较简洁轻松,读起来也比较顺畅. 下面是我根据各个 ...

  8. SqlHelper工具类

    public class SqlHlper { public static readonly string constr = ConfigurationManager.ConnectionString ...

  9. jmeter3.3测试需要登录的接口(java)

    1.新建线程组-略过 2.右键线程组->添加->配置元件->HTTP授权管理器 3.右键线程组->添加->配置元件->HTTP信息头管理器 4.右键线程组-> ...

  10. centos7.2 linux 64位系统上安装mysql

    1.在线安装mysql 在终端中命令行下输入(在官网下载mysql): # wget https://dev.mysql.com/downloads/repo/yum/mysql57-communit ...