天天看點

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

全世界人民對于奇幻故事都非常向往,如果能描繪自己的奇幻世界就太棒了。奇幻世界的基本要素除了故事,就是一張奇幻畫風的地圖了,或者叫Fantasy Map。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線
keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

沒看夠?圖檔搜尋“Fantasy Map”就能看到更多的奇幻地圖。

但是手繪雖然簡單,但非常耗時。于是“懶惰”的大家想出了一個辦法,幹脆用程式去畫吧,隻要輕點滑鼠,一張漂亮的奇幻風格的地圖就生成了。我發現比較好玩的線上奇幻生成器有

1.https://www.makeamap.cn/(非常好用,支援自定義修改)

2.https://azgaar.github.io/Fantasy-Map-Generator/

3.http://bl.ocks.org/Azgaar/b845ce22ea68090d43a4ecfb914f51bd

這些奇幻地圖究竟是如何生成的呢?具體技術可以使用Javascript的SVG,或者C++生成png圖檔的庫。不過這些不是本系列的重點,本系列主要參考了hereDragonsAround的部落格,将與大家讨論如何用程式生成奇幻風格地圖的内在邏輯。

這系列文章将分為六篇

1.基本海岸輪廓線

2.手繪風格的山

3.生物群落

4.森林與海洋

5.名稱标簽的擺放以及雜項

6.地圖上生成蜿蜒河流的方法(附加)

好,現在開始吧。我們看到的奇幻地圖可能都是某個大陸的部分,但如果一開始就繪制大陸的話非常麻煩。是以我們先從簡單的島嶼開始,而地圖邊界自然而然地就用水域填充,島嶼是獨立的,還能限制的奇幻故事發生的範圍。

為了繪制島嶼的輪廓,我們先來生成一個圓。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

這玩意怎麼看都不像一個島嶼對吧?這個圓太标準,我們嘗試重新繪制它的邊界。如下圖a,在圓上随機選擇幾個采樣點,然後用直線連接配接這些采樣點,如下圖b。另一種稍微複雜一些的方法是随機生成一些在指定範圍内的點,然後用凸包連接配接它們,如下圖c。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

島嶼邊界直線又長又直,太難看了,好,我們把它們弄彎。如下圖b,用随機函數添加幾個藍色控制點把長直線拆分成短折線。然後連接配接這些短折線的終點,然後用特殊的曲線算法,比如貝塞爾曲線,或者Catmull-Rom曲線。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

不要被貝塞爾曲線吓到了,我們隻需要用二階貝塞爾曲線即可,比如要生成a,b之間,c為控制點的二階貝塞爾曲線,隻需要按如下方式定義即可。t從0逐漸增加1時,f會有一條圓滑的軌迹,這就是貝塞爾曲線,不過是三個一階乘法而已。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

另一個catmull-rom曲線稍微複雜一些,詳細請看這篇文章。

如果之前使用凸包算法,那麼到現在可能是這個樣子

好了,我們有個近似圓形的輪廓線不規則的島嶼了。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

如果之前使用凸包算法,那麼可能就是這個樣子了。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

島嶼輪廓看起來還是怪怪的,對吧?特别是第一個,還是個圓嘛。

為生成不規則的輪廓。一種常見的技術是使用噪音,多次随機生成噪音并疊加,這樣比較像自然景觀,比如Perlin噪音,這個噪音的特點是噪音是連續的,非常适合生成連續的地形。

所謂Perlin噪音就是下圖這種形狀,不同的灰階代表着高度,黑色的RGB值為[0,0,0],代表着低地,白色的RGB值為[255,255,255]代表着高地。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

可以在這個網站上體驗Perlin噪音生成的地形,比如下面這種:

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

當然這就不是小島了,那麼再用不規則的圓圍一圈就好了嘛。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

最終成果如下:

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

邊緣仍然太規則了,那麼為邊緣繼續添加噪音,一種好方法就是為相鄰的邊緣添加相近的噪音,而不是互相獨立,就能生成各種形狀的邊緣。僞代碼如下:

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

效果如下:

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

先不要關注那些陰影與植被,但目前看來,海洋輪廓線還是不錯的。

除了這些方法,還有一些其他方法,基本思想一樣,先用少數控制點生成大輪廓,再繼續細分,繪制出曲折的海岸線。

比如分形,使用多個分形疊加

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線
keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

RedBlobGame在他的文章中提到的方法是Voronoi圖生成多邊形地形。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

Martin O'Leary在他的文章使用的方法是直接用Delaunay三角形作為邊界

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線
keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

或者幹脆看看《文明5》使用六邊形生成輪廓線,下圖可以看到輪廓線與六邊形邊界并非完全重合。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

學會了生成小島輪廓,那麼生成更多島嶼輪廓自然不在話下。但是這裡還有一個好玩的生成近岸群島的方法。現在島嶼輪廓外圍生成一個多邊形,給這個多邊形賦上地形高度,然後低于某個高度的删掉,就形成了近岸群島了。

keil 生成三角波dac0832_【奇幻地圖程式生成(一)】基本海岸輪廓線

好了,現在我們有了一個光秃秃的島,下面嘗試為它生成一些山。

下一篇:手繪風格的山