3.2 多邊形的交點 [點/多邊形 內/外 測試]

  一旦獲得平面方程,就能夠進行射線/多邊形的交點。在計算射線/平面交叉後,下一步是肯定交點是否在多邊形內。算法

  有許多不一樣的方法能夠解決這個問題。Berlin[1]很好地概述了一些技術。這裏給出的方法是在[14]中提出的「射線相交」算法的一個修改版本。該算法的工做原理是,從交點處向任意方向發射一束射線,並計算相交的線段數。若是交叉的數目是奇數,則點在多邊形內;其餘外。這就是所謂的Jordan曲線定理。圖6描述了這個定理的用法。下面提出的改進算法優雅地處理了測試光線與多邊形頂點相交的特殊狀況。這是我本身的發明,彷佛是一個最佳的解決方案。測試

  以點集定義定義多邊形:spa

    

  定義平面:3d

    

  定義平面的法線(非必要法線):blog

    

  平面與光線的交點:class

    

  第一步是將多邊形投射到二維平面上。在這個平面中,全部的點都由一對(U,V)指定。因此,咱們想要的是每一個[X Y Z]座標都對應一個(U,V)。原理

  一種方法是將平面繞一些軸旋轉,直到法線與其餘軸平行(好比Z)。在這以後,剩下的兩個軸(在這個例子中是X和Y)能夠用來生成(U,V)對。該方案的缺點是必須爲每一個多邊形生成和存儲一個旋轉矩陣,而且必須爲每一個座標執行一個矩陣乘法。方法

  這些成本能夠經過簡單地丟棄[X Y Z]其中一個座標並使用另外兩個來消除。這個動做將多邊形投射到由兩個選定的座標定義的平面上。多邊形的面積沒有保留,可是拓撲結構保持不變。選擇扔掉哪一個座標的定義以下:扔掉絕對值最大的座標。例如,對於一個Pn=[0 -5 3]的多邊形,Y座標會被丟棄,X和Z被分配給U和V (U和V是任意的)。咱們將用最大的座標做爲主導座標。im

   一旦多邊形被投射到平面上,內外測試就至關簡單了。平移多邊形使交點在原點,即從每一個頂點減去交點的座標(Ui Vi)。將這些新頂點標記爲(U',V')。如今想象一條光線從原點出發沿着+U軸運動。對多邊形的每條邊進行相交測試。若是邊緣穿過光線,記錄下來。若是相交的總數是奇數,則點在多邊形內。這個操做如圖7所示。技術

  

   正如Berlin[1]所指出的那樣,在光線上的頂點必須做爲特殊的狀況來處理。這些特殊狀況能夠經過定義它們的方式來避免。沿着+U'軸延伸的光線將平面分紅兩部分。然而,也有一些點在U軸上。必須對位於光線上的頂點(即V' = 0)添加聲明,定義其位於+ V'端。這樣光線上就沒有點了,特殊狀況就消失了。光線自己必須被從新定義爲無限接近原始光線,但不能經過任何點。它如今是一條分界線,而不是一系列的點。

  

  算法的第一次測試(D4)檢查兩頂點的v是否符號不一樣。若是符號相同,則能夠忽略(由於v符號相同則不會與u交叉)。若是兩U都大於0,那麼+U'軸必然與其交叉(D5)。不然,若是端點中的任何一個U>0(D6),則必須找到邊與U'軸相交的準確U'位置(即此直線與U+的截距)。若是(D7)這個截距爲正(即在+U'軸上),那麼這條邊確實與+U'相交。

   該方法比較高效,由於大多數邊緣能夠被平凡地拒絕或接受。 只有當邊緣從對角象限延伸時才須要進行嚴格的計算。

  這個和其餘內-外部測試算法的一個小問題是,在邊緣上的相交點被任意地決定在內部或外部。這個問題是有解決辦法的,可是在實踐中,邊緣上的交點大可能是不相關的。這是由於,若是一個交點落在兩個多邊形之間的邊緣上,而且兩個多邊形都投影在同一個平面上,那麼算法就會肯定這個點在一個多邊形內,而且只在其中一個多邊形內(不考慮精度偏差).

  在圖6中,五角星的中心五邊形不被考慮在恆星內部,由於交叉的數量是偶數。多邊形的另外一個定義是將這些點考慮到多邊形內部。

  要對這類多邊形進行內外測試,須要對以前的算法作一個簡單的修改。改變的是當+U'軸的邊從+V'傳遞到-V'時增長NC,從-V'傳遞到+V'時減小NC。若是NC是0,點在多邊形外面,不然它在多邊形裏面。

  數字NC被稱爲圈數。想象這個多邊形是由繩子構成的,一個鉛筆點被放在交點上。若是弦被拉緊,圈數就是弦繞點的次數。NC的符號是旋轉的方向:‘+’是順時針,‘-’是逆時針。

相關文章
相關標籤/搜索