輪廓布爾運算包括以下運算:反、交、並、差、異或。
一、取反
一個輪廓既可以代表實體也可以代表負實體,約定輪廓逆時針時爲實體輪廓,順時針時爲負實體輪廓,輪廓取反即反轉輪廓方向即可。
二、輪廓交
三、輪廓並
四、輪廓差
五、輪廓異或
兩個多邊形的異或是一個多邊形,其內部區域爲原來兩個多變性差的並
六、其中取反和交是兩種基礎運算,其他運算可以基礎運算的組合來實現
取反:
交:
並:
差:
異或:
七、輪廓交實現
輪廓取反實現就是將輪廓方向反轉,輪廓交實現稍微複雜一點。
兩種方法,先說第一種,以兩個實體輪廓P、Q爲例;
(1)求P、Q交點
(2)最終求交得到的輪廓的頂點由P\Q交點、P在Q內部的頂點、Q在P內部的頂點三部分構成,如下圖
intersection vertex、vertex of P in Q、vertex of Q in P;
(3)這三部分點比較容易求得,那麼接下來的關鍵是這些點的順序問題了,
兩個實體輪廓求教後所得也是一個實體輪廓,即頂點爲逆時針方向,這些頂點是沿着原始輪廓邊一個接一個的連接着的,
即頂點中和原始輪廓P相關的兩部分:intersection vertex、vertex of P in Q,在P看來是沿着P的邊進行排序的;而和原始輪廓Q相關的兩部分:intersection vertex、vertex of Q in P,在Q看來是沿着Q的邊進行排序的。這樣兩個排序好的頂點列表進行合併即得到求教後輪廓的頂點列表;當然合併是有一定規則的。
(4)規則即:1.與P相關的部分:intersection vertex、vertex of P in Q依據在P邊上的位置進行排序得到lstVertexP;與Q相關的兩部分intersection vertex、vertex of Q in P依據在Q邊上的位置進行排序得到lstVertexQ;2.由lstVertexP第一個點出發,若下一個點與當前點在P中的同一條邊上並且它們倆的中點在輪廓Q內,那麼繼續第2步;否則切換到lstVertexQ中與當前點對應的點開始出發,規則同第2步;3.直到形成閉合輪廓,並且這三部分中所有點都已走過;這樣即得到相交的輪廓。
具體過程:當前點爲lstVertexP中點0,由當前點0出發,下一點1與點0同在P的一條邊上,然後當前點爲點1,下一點2與點1不屬於P上的同一條邊,即尋找當前點在lstVertexQ上的位序即lstVertexQ中的點6,當前點爲點6,由當前點出發,下一點7與點6同屬於Q中的一條邊,當前點爲點7,下一點8與點7不滿足條件,點前點切換爲lstVertexP中的點2...最終形成兩個輪廓。
再來看第二種方法,不用於第一種方法以點爲單位尋找下一點來最終構成輪廓,第二種方法以邊爲單位,尋找下一條邊來構成輪廓。
可以看出第二種方法相對較爲簡單,那麼還有可以優化的地方嗎?是的。
八、兩種方法比較
1.第一種以點爲單位,粒度小;第二種以邊爲單位,粒度大,問題規模較小;
2.第二種方法以邊爲單位,邊是有方向的,這樣以邊來尋找下一條邊最終構成輪廓的過程要簡單些;
3.兩種方法都可以優化,第一種求交點過程以及第二種求“交邊”過程可以用空間分區二叉樹來減小計算次數。
我實現了第一種以點爲單位的方法求輪廓交,下載https://download.csdn.net/download/baidu_38621657/11522410
九、其他輪廓布爾運算可通過組合取反、求交運算來實現。
示例效果見文章開始圖片。