
プロシージャル生成技術を用いて、架空の惑星の世界地図を作ってみます。
目次
架空の惑星とは?
じぱんぐライクの紹介を半ば兼ねていたため仕方ありませんが、前回の記事は用途・対象が狭すぎ、あれ以上詳しく掘り下げてもだれの役にも立ちそうにありません。地図のプロシージャル生成といえば、一般に期待されるのは、まったく架空の世界を一から作り出すことでしょう。
この記事では、やはりウェブ地図ライブラリーを使う前提で、架空の“正しい”世界地図の生成を試みます。正しい、というのは惑星として、つまり「球面にしても矛盾しない・破綻しない」世界地図を意味します。
いきなり結論
もったいをつけるような大層な話ではありません。さっさと結論を言ってしまうと、「地図の経緯度の、球面上での3次元座標を引数としてパーリンノイズを得ればいい」だけです。
もうピンと来たかもしれませんが、一応どういうことか、以下に説明します。
パーリンノイズの落とし穴
ご多分にもれず、地形生成にはパーリンノイズを用いるものとします。これは勾配ノイズと呼ばれるたぐいの関数で、連続した値を入力すると、なめらかに続いて見える乱数が出力されます。
たとえばXY座標を引数として平面模様を作ると、ただの疑似乱数では無秩序な砂嵐になるのに対し、パーリンノイズはなめらかなグラデーションを持つもやもやした濃淡になります。濃淡のできる周期を調整しやすいことも特長です。
架空の地図を生成するには大抵、地図平面の経緯度つまりXY座標からパーリンノイズを得て、それを標高などとみなして地形とします。簡単で効果的な方法ですね。しかし平面としてはいいのですが、丸い惑星として見た場合、そうして作った世界地図には問題があります。
地図と地球の関係
わたしたちが地図といえばふつう、メルカトル図法で描かれたものを指すでしょう。これは球体である地球の表面を、展開図のごとく無理やり四角い平面に写しとったもので、南北の極に近づくにつれ経度が文字通り極端に引き伸ばされていきます。
ところで地球上の地形は、標高にせよ海岸線にせよデコボコしており、そのデコボコ具合つまり揺れる頻度・周期は、大まかには世界中どこでも同じくらいです。地球のあっちとこっちで著しく変わる理由もありませんから。
で、あるならば、次のことがいえるはずです。地図上の地形のデコボコの周期は、赤道で最も短く、極に近づくにつれ長くなる。球面上では一定周期であるデコボコが、四角い平面にいびつに引き写された結果そうなるわけです。
一方、「地図平面の経緯度つまりXY座標からパーリンノイズを得て」生成された架空の世界地図のデコボコ具合は、どこも同じ周期です。パーリンノイズへの入力、地図上のXY座標の目盛り間隔は隅から隅まで一定なのですから。したがって、これを球面に写すと、先の場合とちょうど反対に、極に近づくにつれ周期が短くなっていくことになります。惑星の様子としては不自然ですね。
これが第一の問題。周期の違いなど些細なことのようですが、一事が万事です。仮に地形にはさほど違和感がなかったとしても、たとえば都市の構造や交通網ならどうでしょう。要するに、世界を作るときには平面地図ではなく、原型である惑星の球面に基づいて考えねば、どこかいびつになってしまうのです。
世界の果てのつながり
よくある架空の世界地図は、四辺がちょうど海の上で、東西・南北の辺同士がしれっとつながっていたりします(『バンゲリングベイ』や『ドラクエ2』を参照)。そうでない場合は、四辺に見えない壁があり、その先へは行けないことになっています。
後者は世界全体の地図ではないようですが、いずれにせよ、地図の端のつながりを適当にごまかしているか、考えるのを放棄しているのです。言うまでもなく、そうした平面でしか通用しない“ウソ地図”は球面にできません。これが第二にして最大の問題。
球面にしたとき四辺が矛盾なくつながる地図は、やはりあらかじめ球面に基づかねば作ることができません。
地図タイルの球面座標
ウェブ地図ライブラリー用のデータ、XYZ形式の地図タイルは平面です。これはメルカトル図法ですが、より正確には、プログラムで扱いやすく調整した「ウェブメルカトル図法」と呼ばれるもの。
その地図データを球面に基づいて生成するにあたって必要なのは、ウェブメルカトルから球面への座標変換です。平面地図上の座標が、球面上のどの座標にあたるかを対応づけてやるわけです。
なおここで「球面座標」とは、幾何学のいわゆる球面座標系ではなく、単に「球の表面上の3次元座標」との意味で使っています。その座標は普通の直交座標系で表します。
基礎のタイル座標
始めに、XYZ形式の地図タイルがとりうる座標の範囲をはっきりさせます。XYZ形式ではZすなわちズームレベルに応じてXYの目盛りが変わります。目盛りがコロコロ変わっては考えにくいため、適当なズームレベルに基準を置くことにします。とはいえ、これが問題になるのは実装の段階で、今はまだ気にしません。
タイル座標を経緯度に変換
XYZ形式のタイル座標は、次のコードで経緯度に変換できます(度単位)。
N = pow(2, Z)緯度 = atan(sinh(PI * (1 - 2 * Y / N))) * 180 / PI経度 = X / N * 360 - 180
経緯度を球面座標に変換
球面上の座標を求めるには、球そのものの定義が必要です。いまの目的は地球上でのナビや測量ではなく、興味や楽しみのために架空の惑星を作ること。なので地球固有の楕円体だの測地系だのを考慮する必要はなく、適当な半径(とりあえず1でよい)の真球で考えます。
すると、計算はかなり簡単に済みます。球の中心を基準として、緯度はX(またはZ)軸回りの角度、経度はY軸回りの角度。よって、中心から半径ぶん離れた点を、それらの角度で素直に回転させればいいだけです。
球面のパーリンノイズ
地図タイルの球面座標がわかりました。しかし、これがいったい何なのでしょう。何を隠そう、「球面上のパーリンノイズ」を得るのに使えるのです。
球面座標のX・Y・Zそれぞれの値に注目してください。球の中心を原点として半径を1とすると、XもYもZも、-1.0〜1.0のあいだをなめらかに(正弦波のごとく)行ったり来たりしていますね。地図の平面座標において、東西・南北の端で値がぷっつり途切れてしまうのと対照的です。
パーリンノイズが「連続した値を入力すると、なめらかに続いて見える乱数が出力され」る性質であることは述べました。したがって、この途切れなく連続する座標値たちを与えれば、球面のどこをとっても、周囲からなめらかに続く乱数を得られるのです。それを基に地図タイルを作ることで、丸い惑星としても自然な世界地図が出来上がるわけです。
むろんこれを実現するには、3つの引数をとる3次元パーリンノイズ関数が必要です。アルゴリズムを調べて自作してもいいし、出来合いのものを探してもいいでしょう。またパーリンノイズのほかにも、3つの引数をとってユニークな値や連続性のある値(勾配)を返す関数なら何でも、同じ理屈で球面上のプロシージャル生成に利用することができます。
前哨
リクツ編はここまで。文章で「なぜ」から説明したため回りくどくなりましたが、冒頭で述べたとおり、要点はきわめて単純です。わざわざ書くほどでもない気もしつつ、しかしそれが盲点なのか、球面上のプロシージャル地形生成の解説は案外少ないようです。
いつになるかわかりませんが、次には実践編として、架空の惑星の地図をウェブ地図ライブラリーを使って実際に作ってみたいと思います。いざ作ってみたら理屈が間違ってた、なんてこともよくあるので(だから手を動かすことが大切)、この記事をまるごと鵜呑みにはしないほうがいいでしょう。
とはいえ、簡単な実装なら実はとっくにしています。すでにご覧になったかもしれませんが、このサイトの404エラーページには、ちょっとした演出として架空の惑星が表示されます。
ウェブ地図ライブラリーこそ使っていませんが、3次元パーリンノイズで球面の地形を生成する核心は一緒。妥当性を確かめられるほど細かくはないものの、どうやらそれらしい形になっているようです。
用語・注釈
- 「一般に期待される」について
- GIS分野に限っていえば、プロシージャル生成技術に期待されるのは地形生成ではなくディテールの補完だろう。その面でも前回の記事は的が外れている。
- パーリンノイズについて
- 浸透していてわかりやすいから使っているだけで、本文でも述べているように同種の関数なら何でもよい。同じ考案者による改良版「シンプレックスノイズ」を使ってももちろんかまわない。ただし改良版といっても性能と品質のトレードオフがあり、すべての面で優れるわけではないらしい。
- メルカトル図法について
- 実際の地球とメルカトル図法との対応については、GIS開発者なら先刻ご承知だろうし、正確な説明はネット上にも書籍にもたくさんある。劣化版の説明をここで延々繰り返したくないので、詳しくはよそのサイトで調べるか、世界地図と地球儀を調達して見比べてみてほしい。