search
LoginSignup
4

More than 5 years have passed since last update.

posted at

updated at

戦略シミュレーションのような六角形のグリッドを描画する

経緯

-GoogleMaps上に大戦略みたいな六角形のタイルを敷き詰めたい。
-まずはグリッドの座標地図の座標の関係を整理したい。
 →とりあえずpyplotで描画してみることにした。

詳細

 GoogleMaps上に形状を描く場合、座標を緯度経度で指定する必要があるが、
 ゲームのような六角形の座標は水平方向・垂直方向の番号で管理している。

 イメージ
  hexgrid.PNG

 なのでグリッドの座標から地図の座標(もしくはグラフ上の座標)に変換する方法を
 pythonで実装した。(GoogleMapsAPIはJavascriptなので移植前提)

 具体的にはグリッドの座標を[x,y]とする時、
  1. [x,y]→六角形の中心座標に変換[cx, cy]
  2. 各六角形の頂点の座標を計算
  3. 2で求めた座標を結ぶ線分を描画

 となる。

実装

hexgrid2map.py
# 六角形のグリッドを描画する

import math
import matplotlib.pyplot as plt

# hexgridの縦横サイズ
PX = 1
PY = PX * math.sqrt(3)/2

# 一辺の長さ
L = PX / math.sqrt(3)

# 六角形を描画する
def makeHex(cx, cy):
        # 六角形の描画
        # 左の縦線
        plt.plot([cx-PX/2,cx-PX/2], [cy-L/2, cy+L/2], 'k')
        # 右の縦線
        plt.plot([cx+PX/2,cx+PX/2], [cy-L/2, cy+L/2], 'k')
        # 上の右上がり線
        plt.plot([cx-PX/2,cx], [cy+L/2, cy+L], 'k')
        # 上の右下がり線
        plt.plot([cx,cx+PX/2], [cy+L, cy+L/2], 'k')
        # 下の右下がり線
        plt.plot([cx-PX/2,cx], [cy-L/2, cy-L], 'k')
        # 下の右上がり線
        plt.plot([cx,cx+PX/2], [cy-L, cy-L/2], 'k')

def main():
    # 検証用座標列:縦横5個づつ
    mesh_list = [[x,y] for x in range(5) for y in range(5)]

    # グラフ描画
    for x, y in mesh_list:

        # 座標中心を計算
        cx = x*PX if y%2==0 else (x+0.5)*PX
        cy = y*PY
        # 中心点の描画
        an = str(x) + ',' + str(y)
        plt.plot(cx, cy, 'ok')
        plt.text(cx, cy, an, color='red')
        # 六角形の描画
        makeHex(cx, cy)

    # グラフ描画
    plt.show()

if __name__ == '__main__':
    main()

 基本的に垂直方向はタイル1枚分の縦の長さを足していけばいいが、
 水平方向は垂直方向:yの値によって座標が変わるので、yが偶数か奇数か判断して
 cxを決めている感じ。

結果

 Figure_1.png
 ちゃんと描画できた。

今後

 - 座標変換の方法が整理できたので、これを実際の緯度経度に置き換えてみる。
 - 逆に緯度経度からグリッド番号を特定する方法を考える
 - GoogleMapsAPIで実装してみる。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4