在路径规划、游戏设计栅格法应用中,正六边形网格不如矩形网格直接和常见,但是正六边形具有自身的应用特点,更适用于一些特殊场景中,比如旷阔的海洋、区域或者太空。本文主要讲述如何对正六边形进行几何学分析、网格化环境建模、坐标系转换以及正六边形间的关系求解等。六边形的具体代码实现可以参见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. 201521123118《java程序与设计》第4周作业总结

    1.本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点 1.2 使用常规方法总结其他上课内容. 为了不必要写重复的代码,可以运用继承,用关键字extends来定义一个类,被继承的类叫做父类,继 ...

  2. 201521123069 《Java程序设计》 第2周学习总结

    1. 本章学习总结 (1)String类.StringBuilder类(频繁进行字符串的修改应选用StringBuilder,不会生成大量的字符串对象).Math类的用法.字符串池的概念 (2)Sca ...

  3. Servlet的生命周期与运行原理

    Servlet的生命周期:    1 加载classLoader    2 实例化 new    3 初始化 init(ServletConfig)    4 处理请求 service doGet d ...

  4. linux 环境NTP配置与开机自启动(转)

    Linux下配置NTP服务器一.前言:    默认NTP服务端口:    UDP/123    本文配置的NTP工作模式:    使用client/server方式,该方式适用于一台时间服务器接收上层 ...

  5. 运用GRASP原则来做uml交互类图-------pos机实例

    重要的几个GRASP原则:1.控制器模式   2.创建者模式 (原则)3.信息专家模式(原则) 4. 高内聚 低耦合   这里所说的模式并不是java中针对具体的事件的设计模式 主成功场景的几个操作: ...

  6. CacheConcurrencyStrategy五种缓存方式

    CacheConcurrencyStrategy有五种缓存方式:  CacheConcurrencyStrategy.NONE,不适用,默认  CacheConcurrencyStrategy.REA ...

  7. Java实现CORS跨域请求

    问题 使用前后端分离模式开发项目时,往往会遇到这样一个问题 -- 无法跨域获取服务端数据 这是由于浏览器的同源策略导致的,目的是为了安全.在前后端分离开发模式备受青睐的今天,前端和后台项目往往会在不同 ...

  8. 读Zepto源码之Gesture模块

    Gesture 模块基于 IOS 上的 Gesture 事件的封装,利用 scale 属性,封装出 pinch 系列事件. 读 Zepto 源码系列文章已经放到了github上,欢迎star: rea ...

  9. 《HiBlogs》重写笔记[1]--从DbContext到依赖注入再到自动注入

    本篇文章主要分析DbContext的线程内唯一,然后ASP.NET Core的注入,再到实现自动注入. DbContext为什么要线程内唯一(非线程安全) 我们在使用EF的时候,可能使用相关框架封装过 ...

  10. 支持向量机SVM(二)

    [转载请注明出处]http://www.cnblogs.com/jerrylead 6 拉格朗日对偶(Lagrange duality) 先抛开上面的二次规划问题,先来看看存在等式约束的极值问题求法, ...