English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

guest
1 / ?
back to lessons

Flatland 類比

Edwin Abbott 的《Flatland》(1884):二維平面上的居民。他們只能感知長度與寬度。深度——位於他們上方的第三維度——對他們而言是不可見的。他們無法感知、無法使用,也無法用它來建造。世界的幾何結構包含一個他們在結構上捨棄的維度。

MOAD-0007 的運作方式與此相同。三維空間中的物件帶有位置、旋轉與邊界體積:這是一種豐富的幾何結構。線性掃描卻將它們視為一張平面清單。空間結構存在,卻未被使用、被捨棄。每一次交集測試都必須掃描整個清單,彷彿這些物件沒有幾何也沒有位置。

BVH 與平面清單:O(log N) 查詢可剪枝空間區域,而 O(N) 則進行完整掃描

Three.js 範例

Three.js Raycaster.intersectObjects():給定一條射線(3D 空間中的位置與方向),找出所有與該射線相交的物件。其實作方式是:逐一迭代場景中的 N 個物件,對每個物件進行射線測試。每次呼叫的時間複雜度為 O(N)。

一個 hover 事件處理函式每秒以 60 幀的頻率呼叫 intersectObjects()。當 N=100 個物件時,每秒進行 6,000 次交集測試;當 N=10,000 個物件時,每秒進行 600,000 次測試。成本與 N 成正比,而非與射線實際交集的物件數量成正比。

當 N=100 時:幾乎感覺不到。60fps 下的 16.7ms 畫面預算足以吸收這項成本而不會有任何抱怨。

當 N=10,000 時:成為主要負擔。600,000 次交集測試每秒佔滿主執行緒,導致畫面幀率下降。原本在 N=100 時運作順暢的場景,會在 N 跨越門檻時悄然崩潰。

線性掃描所丟棄的結構

物件在空間中佔有位置。一個位於 (1000, 0, 0) 的物件,不可能與從 (0, 0, 0) 朝 (-1, 0, 0) 方向發出的射線相交:該物件位於相反方向。線性掃描仍會對它進行檢查。

物件具有邊界體積:一個包圍整個物件的球體或盒子。若射線未與物件的邊界體積相交,則不可能與該物件本身相交。線性掃描仍會執行完整的交集測試。

幾何結構編碼了哪些物件可以跳過。線性掃描卻忽略了這項幾何資訊。這就是所謂的「丟棄」。

「捨棄結構」的意義

Flatland 比喻:Abbott 的居民無法感知深度。Flatland Defect 會捨棄資料中原本存在的幾何結構,而演算法從未接觸到這些結構。

「捨棄結構」對空間資料而言意味著什麼?BVH 如何避免這種捨棄?

為什麼雜湊集合無法解決 MOAD-0007

MOAD-0001 修正:將循序成員測試替換為雜湊集合。list.contains(x):O(N)。set.has(x):O(1)。成員測試問題:「x 是否存在於此集合中?」不涉及空間幾何。

MOAD-0007 修正:將線性空間掃描替換為空間索引(BVH、八叉樹、k-d 樹、R 樹)。空間問題:「此集合中哪些物件與此射線/球體/視錐體相交?」需要空間鄰近性。

雜湊集合回答成員問題:「此精確物件是否存在?」O(1)。它無法回答鄰近問題:「哪些物件靠近此射線?」雜湊集合沒有距離或空間範圍的概念。雜湊會徹底捨棄幾何資訊,就像線性掃描一樣。

BVH 回答鄰近問題:「哪些物件落在此空間查詢範圍內?」O(log N + k)。它依據位置組織物件,因此鄰近查詢會跳過幾何上遙遠的物件。

問題正確結構錯誤結構
物件 X 是否在此集合中?HashSet (O(1))線性列表 (O(N))
哪些物件與此射線相交?BVH/八叉樹/k-d 樹 (O(log N))線性掃描或 HashSet (O(N) 或 O(N))

MOAD-0001 與 MOAD-0007:兩者皆為 O(N) 操作,改用更快的演算法。因為問題不同,所以需要不同的資料結構。

何時建立、何時略過

建立 BVH 的成本為 O(N log N),查詢成本為 O(log N + k)。當查詢次數足夠多,使得查詢節省的時間超過建立成本時,即達到平衡點。

當 N=100 時:線性掃描只需數微秒。BVH 的建立反而增加額外開銷。此時應略過 BVH。

當 N=10,000 且以 60Hz 執行時:線性掃描會佔用大部分的畫面時間。BVH 查詢成本僅為線性掃描的 1/1,000。建立一次 BVH,每秒查詢 60 次。平衡點在第一個畫面之前即已達到。

規則:當 N * Q > N log N 時建立 BVH,其中 Q 為每次重建週期內的查詢次數。對於互動式 3D 場景:Q = 每秒 60 次,N 的門檻約為數百個物件。

診斷與修復 3D 場景

某 3D 視覺化應用程式渲染 5,000 個幾何物件。滑鼠懸停事件每秒觸發 60 次。每次懸停事件發生時,處理函式呼叫 scene.intersectObjects(ray, objects),此函式會遍歷全部 5,000 個物件並逐一進行射線測試。畫面更新率從 60fps 下降至 8fps。

一位隊友建議:「將所有物件放入 Set 以達到 O(1) 查找。」

辨識缺陷類別。將其與 MOAD-0001 區分。解釋為什麼 Set 建議無法修復此問題。描述正確的修復方式。