相交檢查次數(checks):0
灰色=尚未進入活動集合或已離開;藍色=活動集合中的線段;紅色(粗)=當前處理的線段;橘色虛線=已發現相交的線段;黃色垂直虛線=掃描線目前位置。
點旁數字為線段端點在座標陣列中的索引(非線段編號),線段編號請對照下方面板。
想知道一堆線段裡哪些互相交叉——好比地圖上哪些道路會相交——最笨的辦法是把每兩條都拿來比一次,線一多就慢得離譜。掃描線(Sweep Line)換個聰明做法:想像一把直尺從左往右緩緩掃過整個畫面,只盯著直尺此刻碰到的那幾條線彼此檢查,還沒碰到的就先擱著、掃過去的就放掉。這樣就把「全部兩兩比對」縮小成「只比此刻靠在一起的」。下面你會看到那把直尺一路掃過,線段陸續進出活動集合,交叉點被一個個抓出來。
掃描線(Sweep Line)是計算幾何常見的範式:把每個幾何物件拆成「事件(event)」,依掃描方向(此處為 x 座標)排序後逐一處理, 同時維護一個隨掃描進度增減的活動集合(active set),只跟活動集合內的物件比較,避免對所有物件兩兩窮舉。 這裡的簡化版線段相交偵測:每條線段拆成「開始(左端點)」「結束(右端點)」兩個事件;開始事件與活動集合中每條線段檢查是否相交,再把自己加入活動集合; 結束事件則把自己從活動集合移除。(誠實標注:本頁為簡化版,每個開始事件與整個活動集合逐一比對,最壞情況 O(n² log n); 完整 Bentley-Ottmann 用平衡樹維護線段的 y 序、只比對相鄰線段,可達 O((n+k) log n)。)