NavMesh尋路中的漏斗算法

轉自:https://www.cnblogs.com/pointer-smq/p/11332897.html

 

NavMesh是廣泛使用的一種尋路技術,將地圖中可走的部分生成連續的多邊形/三角形網格,尋路在網格中進行,主要包含兩步:1、根據網格的鄰接信息構造圖,使用A*之類的尋路算法計算出從起點到重點需要走過的多邊形/三角形集合;2、使用漏斗算法/拉繩子算法,將多邊形列表轉換爲一條最優的路店。本文主要講一下對於三角形列表的漏斗算法原理。

諸位讀者如果搜索過網絡,會發現有一年GDC有人講了這個算法,也有幾篇博客翻譯了這個GDC的演講slides,但多半都是僅僅翻譯一遍slides的水平,沒有真的把算法說明白,導致筆者在實現這個算法的時候遇到了很大的困難,好在最後還是弄懂了。

閱讀本文需要一定的前置知識,您需要知道NavMesh及其對應的三角形網格,以及單位在NavMesh中尋路的三角形列表中間結果。

 

算法結果

如圖所示,假定左邊的三角形列表是從尋路算法生成的從起點到終點需要經過的三角形,兩個藍色圓點分別是起點和重點;右邊綠色的粗線就是算法的結果,是從起點到終點需要經過的最短路徑。

image


 

算法過程

  • 首先計算出三角形列表中的鄰接邊列表,所謂鄰接邊就是兩個三角形公用的邊,然後從起點開始,構造到第一條鄰接邊的漏斗,算法正式開始。

黃色的邊均爲鄰接邊,兩條綠色的邊爲初始的漏斗,姑且約定兩條“漏斗邊”的“起點”爲藍色圓點,方便後文的描述

image

  • 將兩條漏斗邊的終點移動到下一條鄰接邊,對於途中的情況,左邊的邊沒有動(但邏輯上算移動了),右邊的邊向內收緊了。

分別考慮兩條邊的角度變化,當漏斗變窄(或不變化)時,本次移動是有效的,否則需要對那條邊回退操作,對於圖中情況,移動是有效的

可見圖中的漏斗變窄了

image

  • 繼續將漏斗邊的終點移動到下一條鄰接邊,漏斗繼續收緊,移動有效,之後的兩步操作都和上圖情況相同

imageimage

  • 下一步操作出現了第一種特殊情況,漏斗邊終點移動到下一條鄰接邊時,漏斗口的角度變爲了負數(原來右邊漏斗邊轉到了左邊去),這種情況下,被蓋過去的那條邊的終點就成爲了結果中的第一個點。

同時,將漏斗起點移動到該點,以當前漏斗起點所在三角形的出鄰接邊構造漏斗,繼續算法

imageimage

  • 使用之前描述的規則繼續收緊漏斗口

imageimageimage

  • 繼續移動漏斗,這一次會發現左邊的漏斗邊沒有移動,而右邊的漏斗邊會使漏斗口變大,右邊的移動是無效的。這次移動只有左邊發生了移動(雖然起點和終點一樣)

image

  • 下面是算法的結束情況,算法已經移動到了最後一條鄰接邊,但是從現在的漏斗底直接連一條線到終點肯定是不可行的。隨後我們以終點一個點,當作一條兩條端點相同的邊。用它繼續前進漏斗口。

右邊的漏斗邊如果移動,會使漏斗口變大,因此不移動,左邊的漏斗邊移動,會蓋過右邊的漏斗邊,因此右邊的漏斗邊終點成爲了結果中的另一個點。

image

  • 同樣,以該點所在三角形的出鄰接邊重新構造漏斗,繼續算法,很快就會發現漏斗口到終點,收到了最小,算法結束。

imageimage

 

 

 

//-----------------------------------------

轉自:https://blog.csdn.net/yxriyin/article/details/39207709?utm_source=blogkpcl6

由於中文方面幾乎沒有說明,英文也要翻牆看,太麻煩了,這裏做一下筆記。

原理很簡單,就是判斷下一個點是在漏斗範圍內,就直接移動過去。如果出了範圍,那麼就設置成一個點,重新一輪漏斗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章