<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

深入探索AOI算法的設計考慮因素

新機器視覺 ? 來源:知乎 ? 2024-01-03 14:02 ? 次閱讀

作者:co lin

【導讀】:網上關于AOI算法的文章很多了,但大多語焉不詳,一上來就9宮格十字鏈表,直接把人整懵。本文試圖由淺入深的介紹AOI算法的形成,希望能把AOI解決的問題,以及它的核心邏輯講清楚。如果讀完之后能所有啟發,那本文的目的就達到了。

AOI 算法是大型多人在線的游戲服務器中一個非常重要的基礎模塊,它很大程度上決定了服務器的運行效率。那么什么是AOI呢?AOI全稱為Area Of Interest,翻譯過來叫感興趣的區域,通俗的講是一個游戲對象在場景中的視野,這個視野可以大到整個場景,也可以小到周圍幾米;它能觀察到視野中的其它對象的一舉一動,同時它也在某些對象的視野中,也被這些對象觀察著。

每個對象需要維護到兩個集合:

觀察者集合:就是關注我的對象集合,我的所有AOI行為都需要向這個集合發送事件,以便讓他們觀察到我的變化。

被觀察者集合:就是被我關注的對象集合,理論上只要有觀察者集合就夠了,為什么還需要維護一個被觀察者集合呢?因為有時候想主動檢查對象的狀態,比如怪物AI會定時檢查被觀察者集合的距離,決定是否發動攻擊;又比如釋放技能需要遍歷被觀察者集合,判斷它們是否命中。如果沒有被觀察者集合,就必須遍歷整個場景的對象。

有些游戲對象同時擁有這兩個集合,有些只擁有其中一個,假設場景中有玩家,怪物,NPC,掉落物:

圍繞這兩個集合,AOI算法的設計要考慮以下因素:

現在我們就一步步地探索AOI算法。

上帝視角

把整個場景當成可見范圍,無論我走到哪里,都能看到場景中的所有對象。每個對象就像上帝一樣,能觀察到其他對象的行為。

這種做法是為最簡單直接的AOI管理,場景管理器只需用一個字典保存所有游戲對象,另有一個字典按對象類型保存對象集合就可以了。被觀察者集合和觀察者集合在需要的時候直接從場景管理器中取。

以一個玩家在場景中的行為看看AOI怎么處理

進入

我進入場景,取出所有對象,向我發送Enter(對象)事件,我會向客戶端發送對象集進入的協議,這樣我的客戶端便能看到場景中的所有對象。

將我加入場景管理器。

取出其他玩家集合,向它們一個個發送Enter(我),玩家會向它的客戶端發送我進入的協議,這樣它就能看到我在場景中,即便我其實離屏幕很遠也是這樣。

可能不需要向怪物集合發送Enter消息,因為怪物AI會自己去遍歷敵人。

離開

我離開場景,將我從場景管理器刪除。

取出玩家集合,向它們一個個發送Leave(我)事件,玩家會向它的客戶端發送我離開的協議。

可能不需要向我發送Leave(對象)事件,因為我跳場景后,客戶端會自動把場景中的對象刪除。

更新

我在場景中的行為稱為更新,比如移動,換裝,發技能等等,其他玩家應該能看到我這些行為。

取出玩家集合,向它們發送相應的事件,他們會向客戶端發送相應的協議,這樣客戶端就能看到我的行為了。

上帝視角的AOI其實是非常簡單可靠的,如果預估場景中的對象最多幾十個,那么我建議直接用這種方式,它即足夠高效,也不用每個對象單獨保存觀察者集合和被觀察者集合,對內存很友好,同時它很簡單,幾乎不大可能出錯。

但當場景比較大,且對象數量達到數百上千的時候,這種方式就不適合了,因為每個對象的狀態更新需要通知上千個其他對象,交叉起來能達到百萬級別的量。再加上客戶端承受不了上千的游戲對象,我們應該減少對象的視野。

減少視野

一旦限定了對象的視野,AOI算法就開始變得復雜;而且每個對象需要維護被觀察者集合和觀察者集合,內存占用會大大增加。

每種對象的視野可以不同,比如玩家的視野只比一個屏幕大一點點,有些BOSS需要更大的視野,而NPC可能視野為0,視野為0的對象不關注別人,只被別人關注。

看看減少視野后的處理

進入

我進入場景。

遍歷場景中所有對象,逐一比較它們和我的距離,如果對象在我的視野之內,則向我發送Enter(對象)事件,此時這些對象會加入我的被觀察者集合,同時,我會加入到這些對象的觀察者集合。

同樣如果距離小于對象的視野,則向對象發送Enter(我)事件,此時我會加入到對象的被觀察者集合,同時對象會加入到我的觀察者集合。

離開

我離開場景。

遍歷我的觀察者集合,向他們發送Leave(我)事件,此時我從對象的被觀察者集合中刪除,同時對象也會從我的觀察者集合刪除。

遍歷我的被觀察者集合,將我從這些對象的觀察者集合中刪除,將我的被觀察者集合清空。

更新

這里的更新不包括移動,因為移動會導致對象集合變化。遍歷我的觀察者集合,向它們發送相應的更新事件。

移動

我移動的時候,被觀察者集合和觀察者集合都會發生變動,現在我們沒有好的辦法優化它,只能這樣做:

遍歷場景的所有對象:

別被這段話繞暈,實際上它的邏輯是很清楚的,請仔細理解這段話。

可以看到移動是最大的性能瓶頸,每次移動需遍歷場景中的所有對象,如果每個人都在移動,那這個服務器的承載力可想而知?,F在的優化方向轉向如何減少對象的遍歷,稍微思索后,我們能得到一個解決方法:將場景劃分格子。

網格化

將場景劃分成等大的格子,1個格子大約為1/4屏幕大小,每個進來的對象根據坐標加入對應的格子中,如下圖所示:

e21b2b68-a943-11ee-8b88-92fbcf53809c.png

綠色框為屏幕大小,紅星為我,現在我們把最大視野限定為9宮格,這樣搜索范圍就縮小為9個格子,需要遍歷的對象數量大大減少。

進入

我進入場景,馬上計算出我所在的格子,并加入這個格子。

接下來的做法和上面的進入完全一樣,只不過搜索的范圍變成這9個宮格子,具體不再描述。

離開

我離開場景,將我從格子刪除,

接下來的做法和上面的離開完全一樣。

移動

我移動的時候,遍歷9宮格的所有對象,然后執行和上面的移動完全一樣的邏輯

如果我移動到新的格子上時,還要多處理一些事件:

如果對象均勻的分布在場景中,且場景足夠大,那這個優化的效果是非常顯著的。

但如果像主城那樣,玩家大多集中在一個區域,服務器的壓力仍然會很大,原因是9個格子的玩家可能占了場景80%的玩家,這又退化成和遍歷場景所有玩家差不多了。

假如我們把要求降低一些:強制對象的視野固定在9宮格上,也就是說,只要我在這個格子中,不管怎么移動,視野都是周圍的9個格子,那事情就好辦了。每個游戲對象不需要維護兩個集合,直接從9宮格里取即可?,F在邏輯簡化成這樣:

e22b6dd4-a943-11ee-8b88-92fbcf53809c.png

這個過程看起來就是上帝視角的縮小版,如果我們對視野要求不那么高,這個做法和上帝視角一樣簡單可靠。我相信很多游戲的9宮格處理都是用這種,或者基于這種去優化的。

這種做法的一個小小缺點是客戶端會收到一些屏幕外的對象消息,有點浪費帶寬吧,如果我們把發消息做成批量加壓縮的方式,這種浪費并不大。

十字鏈表

基于網格的優化基本也就到這兒,如果想探索更多的優化方式,只能換一種數據結構,用十字鏈表,其核心思想是將所有對象結點鏈接在兩個鏈表上,一個按X值排序,一個按Y值排序,對象進入場景后遍歷兩個鏈表,找到合適的位置插進去;移動的時候,從對象位置前后遍歷兩個鏈表,和其他對象進行判斷。

簡單的描述是這樣子,可是當你按這個思路去實現十字鏈表時,你會發現搜索觀察者和被觀察者都很慢,因為每種對象的視野可能不一樣,你沒辦法只前后遍歷一點點,有可能在很遠的地方有一個對象在觀察著你,你只能整個鏈表遍歷,這樣的十字鏈表就沒什么意義了。

真正的十字鏈表,除了對象結點外,還需要一種哨兵結點,每個對象都帶有兩個哨兵結點,這兩個哨兵結點同樣被鏈接在X和Y鏈表上,哨兵結點也有坐標,它們的坐標剛好是對象坐標與其視野半徑的差值,舉個例子:

對象A的坐標是(100, 90),假設對象的視野半徑是20,那么哨兵1的坐標就是(80, 70),哨兵2的坐標就是(120, 110),它們按順序加入鏈表,拿X鏈表舉例,如下所示:

e23a8760-a943-11ee-8b88-92fbcf53809c.png

先不去管B和C,a1和a2是A的哨兵,并且A移動后,哨兵也會跟著移動,以保持它們的距離總是視野的半徑。

那么哨兵結點的作用到底是什么呢?顧名思議,它們的作用是用來監控跨越它的對象結點的:

假如有一個D結點原來的坐標是(78, 69),現在它移動到(82, 75),坐標變動后,D結點需要從原來的位置向前移,必定會跨過a1這個結點,此時a1判斷D是一個對象結點,且它原來的坐標在A的視野之外,現在的坐標到了A的視野之內,就可以確定D進入A的視野。哨兵向A發送Enter(D)事件:D會加入A的被觀察者集合,同時,A會加入到D的觀察者集合。

D在向前移動時,A也可能會進入D的視野,這個是怎么判定的呢?別忘了D也是有兩個哨兵結點的,它們也跟著D向前移,其中一個哨兵越過A時判斷:原來A的坐標在D的視野之外,現在A的坐標到了D的視野內,可以確定A進入D的視野,于是哨兵向D發送Enter(A)事件:A會加入D的被觀察者集合,同時,D會加入到A的觀察者集合。

如此一來一回,各方就慢慢維護起觀察者集合和被觀察集合。離開視野的處理也是類似,這里就不再羅索,留給你們去想。

總而言之,十字鏈表的的核心算法就是哨兵結點或對象結點在移動的時候,會跨過對方,在跨過的時候判斷進入視野還是離開視野。

這個算法假設對象經常靜止或小幅移動,對于大幅移動和進出場景是小概率事件,這個假設用在網游剛好非常湊效,所以十字鏈表非常高效。

下面用一個幾何圖來幫助理解十字鏈表:

e24db916-a943-11ee-8b88-92fbcf53809c.png

A移動到A'時,所需要遍歷的對象就在黃條覆蓋的區域,這個條越細表示遍歷的對象越少。

當然也不是說十字鏈表很完美,它在角色經常進出場景的情況下就表現得不大好,因為角色每次進來場景,都需要從X和Y的鏈表頭向前遍歷,直到找到自己的位置。這個時間復雜度是O(N)。遇到那種經常跳場景去副本的游戲,十字鏈表可能會有點性能瓶頸。

針對這個問題,我想到了一種解決辦法,注意看了:

地標結點越多越精確,但遍歷的結點也越多,這個需要實際實現的時候做試驗。

AOI算法大體就是這樣,大多數游戲用固定視野的9宮格算法就足夠了,如果人數太多,我們完全可以用場景分線或分層的方式,強制把人數降下來,因為人數太多,對客戶端的體驗也不會好到哪里去。

本文到此就結束了,希望對正在研究AOI算法的你有所幫助。

對玩家來說:它能觀察到所有類型的游戲對象;同時它會被其他玩家和怪物觀察著;但它可能不會被NPC和掉落物觀察。所以它的被觀察者集合是所有類型的游戲對象,觀察者集合是玩家和怪物。

對于NPC和掉落物來說:它不關心周圍的對象,所以它沒有被觀察集合;但它有觀察者集合,里面只有玩家類型。

怪物多樣化一些:

主動怪的被觀察者集合是玩家;觀察者集合也是玩家。

被動怪可以設計為沒有被觀察者集合,因為在它沒有被玩家攻擊之前,它是不關心周圍的環境,玩家攻擊它之后,玩家會進入它的仇恨者列表,這是怪物AI的范疇了;它的觀察者集合是玩家。

對象視野的大小,這直接影響到集合的大小。

對象集合保存在哪里,有些做法是場景共享對象集合,有些則是每個對象單獨保存這兩個集合。

在進入離開移動等事件中,如何更新對象集合。

如果它原來在我的被觀察者集合中,并且現在的距離已經大于我的視野,向我發送Leave(對象)事件,此時對象會從我的被觀察者集合刪除,同時我會從對象的觀察者集合刪除。

如果它原來在我的觀察者集合中,并且現在的距離已經大于它的視野,則向它發送Leave(我)事件,此時我會從它的被觀察者集合中刪除,同時它會從我的觀察者集合中刪除。

向剩下的觀察者集合發送移動事件。

如果它原來沒有在我的被觀察者集合中,并且現在的距離已經小于等于我的視野,向我發送Enter(對象)事件,此時這些對象會加入我的被觀察者集合,同時,我會加入到這些對象的觀察者集合。

如果它原來沒有在我的觀察者集合中,并且現在的距離已經小于等于它的視野,向它發送Enter(我)事件,此時我會加入到對象的被觀察者集合,同時對象會加入到我的觀察者集合。

把我從原來的格子刪除,加入新的格子。

假設舊的9宮格為OldGrid,新的9宮格為NewGrid,計算{NewGrid-OldGrid}集合,得到的這些格子即為新增的格子。然后對這些格子執行和進入完全一樣的處理:

進入場景:進入一個格子,取出周圍9格的對象,向它們發送Enter(我)事件,同時向我發送Enter(對象)事件。

離開場景:取出周圍9格的對象,向它們發送Leave(我)事件。

移動:

如果沒跨格子,直接取9格的對象,向它們發送移動事件。

如果跨過格子,計算{OldGrid-NewGrid},向它們發送Leave(我)事件,向我發送Leave(對象)事件;計算{NewGrid-OldGrid}集合,向它們發送Enter(我)事件,向我發送Enter(對象事件;計算{NewGrid*OldGrid}集合,向他們發送移動事件。

首先需要像9宮格那樣限定一個最大視野,比如任何對象的視野都不會超過1.5個屏幕大小。

接著我們定義一些地標結點,它們的坐標在設定之后就不會改變,像是地圖里的地標一樣。假如一個地圖的大小是1000x1000,我們可以創建10個地標結點,每個結點的坐標相距100大?。篗1(0, 0), M2(100, 100), M3(200, 200), M4(300, 300)。。。

創建場景的時候,就把地標結點分別插入到X和Y鏈表中,地標結點的坐標不會改變,所以永遠不用移動它們。

接著把這些地標結點按順序保存在一個數組中:|M1|M2|M3...|,有了這個數組,我們就不用從頭移動了。

A進入場景后,它算出:移動點=A的坐標-最大視野直徑,然后在地標數組中快速查找到最近的地標結點(用二分查找法),從這個地標結點開始向前移動,移動過程中A就會進入其他對象的視野。

A移動完成之后,A身邊的兩個哨兵結點開始向兩邊移動,移動過程中就會有一些對象進入A的視野。

審核編輯:黃飛

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 算法
    +關注

    關注

    23

    文章

    4468

    瀏覽量

    91031
  • AOI
    AOI
    +關注

    關注

    6

    文章

    135

    瀏覽量

    24169

原文標題:深入探索 AOI 算法,縷清核心邏輯

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    為什么說“AOI檢測”是SMT焊接質量的把關者?

    、 無焊錫 :AOI能夠檢測是否存在無焊錫的情況。 12、 多錫 :AOI能夠檢測是否存在多錫的情況。 三、SMT不良原因的應對辦法 ◆ 影響AOI檢查效果的因素
    發表于 04-25 11:56

    選擇ITX主板時要考慮因素

    為您的構建選擇合適的ITX主板需要仔細考慮幾個因素。雖然性能和兼容性至關重要,但還有其他方面需要牢記。以下是選擇ITX主板時需要考慮的一些關鍵因素:處理器兼容性:確保您選擇的ITX主板
    的頭像 發表于 02-19 10:41 ?326次閱讀
    選擇ITX主板時要<b class='flag-5'>考慮</b>的<b class='flag-5'>因素</b>

    一張圖看懂“PCB設計考慮因素

    一張圖看懂“PCB設計考慮因素
    的頭像 發表于 11-23 18:15 ?596次閱讀
    一張圖看懂“PCB設計<b class='flag-5'>考慮</b>的<b class='flag-5'>因素</b>”

    電流反饋運算放大器噪聲考慮因素是什么?

    電流反饋運算放大器噪聲考慮因素
    發表于 11-23 07:57

    LED照明設計需要考慮因素

    電子發燒友網站提供《LED照明設計需要考慮因素.pdf》資料免費下載
    發表于 11-13 10:43 ?0次下載
    LED照明設計需要<b class='flag-5'>考慮</b>的<b class='flag-5'>因素</b>

    選擇SMT貼片機的考慮因素

    在電子制造業中,表面貼裝技術(SMT)貼片機是生產線的核心設備。然而,市場上有許多不同型號的SMT貼片機,選擇最適合自己需求的設備,需要從多個方面進行深入考慮。以下是需要考慮的幾個關鍵因素
    的頭像 發表于 08-22 14:25 ?344次閱讀

    新一代DIP波峰焊AOI詳細介紹

    AOI是電子廠檢查PCBA線路板有效的檢測方法,使用視覺加算法技術,以影像處理來檢出元件和焊點等瑕疵。但傳統AOI通過抽色和復雜算法,導致編程復雜繁瑣和調試時間長并且誤判多等不足,傳統
    的頭像 發表于 08-18 09:33 ?1553次閱讀
    新一代DIP波峰焊<b class='flag-5'>AOI</b>詳細介紹

    深入探索感應馬達的生產過程

    本文將深入探索感應馬達的生產過程。盡管各廠商的馬達細節設計有所異同,我們還是將以最基礎的生產模式為主要脈絡來進行闡述。
    的頭像 發表于 08-16 16:23 ?951次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>探索</b>感應馬達的生產過程

    AP3407/A的設計考慮因素

    電子發燒友網站提供《AP3407/A的設計考慮因素.pdf》資料免費下載
    發表于 07-25 16:10 ?0次下載
    AP3407/A的設計<b class='flag-5'>考慮</b><b class='flag-5'>因素</b>

    AP3512E/3E的設計考慮因素

    電子發燒友網站提供《AP3512E/3E的設計考慮因素.pdf》資料免費下載
    發表于 07-25 14:26 ?0次下載
    AP3512E/3E的設計<b class='flag-5'>考慮</b><b class='flag-5'>因素</b>

    AP3502E/3E的設計考慮因素

    電子發燒友網站提供《AP3502E/3E的設計考慮因素.pdf》資料免費下載
    發表于 07-25 10:34 ?0次下載
    AP3502E/3E的設計<b class='flag-5'>考慮</b><b class='flag-5'>因素</b>

    AP3031的設計考慮因素

    電子發燒友網站提供《AP3031的設計考慮因素.pdf》資料免費下載
    發表于 07-24 17:41 ?2次下載
    AP3031的設計<b class='flag-5'>考慮</b><b class='flag-5'>因素</b>

    選購螺桿支撐座要考慮哪些因素?

    選購螺桿支撐座要考慮哪些因素?
    的頭像 發表于 07-13 17:41 ?466次閱讀
    選購螺桿支撐座要<b class='flag-5'>考慮</b>哪些<b class='flag-5'>因素</b>?

    深入探索SMT貼片檢測技術:X-RAY、人工和AOI光學檢測

    表面貼裝技術(SMT)是現代電子設備制造的核心。在其生產過程中,一種重要的步驟就是檢測,確保組件和焊點的質量和完整性。三種常見的SMT貼片檢測方法是X-RAY檢測、人工檢測和AOI光學檢測。這些方法有著不同的特點,適應不同的應用場景。
    的頭像 發表于 06-18 10:10 ?1533次閱讀
    <b class='flag-5'>深入</b><b class='flag-5'>探索</b>SMT貼片檢測技術:X-RAY、人工和<b class='flag-5'>AOI</b>光學檢測

    AOI 顏色&amp;缺陷檢測原理

    原理 AOI 原理有光學的反射原理、光成像原理和檢測算法。 NO 3.?AOI 檢測硬件系統 3.1 現場實物圖 3.2?AOI 檢測硬件 1. 相機; 2. 白色墊板:電池片停留的位
    的頭像 發表于 06-16 14:20 ?1336次閱讀
    <b class='flag-5'>AOI</b> 顏色&amp;缺陷檢測原理
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>