Voronoi Diagram (DEMO)
實作 Voronoi Diagram 演算法,可用滑鼠在畫布上點選座標,亦可透過文字檔輸入座標點,以 Divide and Conquer 來處理四個點以上的運算,最後用 Step by Step 的方式來輸出結果。
- 滑鼠在畫布上任意點擊,畫布大小為 603*603
- 輸入x軸及y軸座標
- 隨機產生數個點
- 讀入「輸入文字檔」,《詳細格式》
- 讀入「輸出文字檔」,直接在畫布繪出圖形
- 按下Save,輸出「輸出文字檔」
- 輸出文字檔格式如下:
輸入的座標點:P x y // 每個點佔一行,兩整數 x, y 為座標。
線段:E x1 y1 x2 y2 // (x1, y1) 為起點,(x2, y2) 為終點,其中 x1≦x2 或 x1=x2, y1≦y2
座標點排列在前半段,線段排列在後半段。
座標點以 lexical order順序排列(即先排序第一維座標,若相同,則再排序第二維座標;線段亦以lexical order順序排列。 - 輸出文字檔案範例:
P 100 100
P 100 200
P 200 100
P 200 200
E 0 150 150 150
E 150 0 150 150
E 150 150 150 600
E 150 150 600 150
(Clear):清除畫布
(Open):開啟檔案
(Save):輸出檔案
(Next):讀取下一筆資料
(Run):執行
(Step):Step By Step
(Add):加入指定座標點
(Random):產生隨機點
(About):關於
以「隨機+共線」的情況,來測試以下幾種點個數的範圍:
- 1~3 點:三點以下直接解
- 4~6 點:三點以上會 Divide 及 Merge 一次
- 7~12 點:七點以上會 Divide 及 Merge 多次
- 大於 12 點:多點測試
- 下載主程式後,執行「VoronoiDiagram.exe」即可。
於畫布區繪製點座標,有以下幾種方法:
我是使用C#原本就有的PointF型態來儲存點座標,自己額外再建了以下三種結構:
- Edge:儲存線段的結構
PointF A; // 線端點A座標
PointF B; // 線端點B座標
PointF a; // 做中垂線的點a座標
PointF b; // 做中垂線的點b座標
- Voronoi:儲存Voronoi Diagram的結構
List<PointF> pList; // 座標點集合
List<Edge> hpList; // Hyper Plane 集合
List<Edge> vList; // Voronoi 集合
- Record:儲存紀錄的結構,用於Step By Step功能
List<PointF> pList; // 點集合
List<Edge> eList; // 線段集合
int type; // 類型
bool clear; // 是否需要清除之前的步驟
bool enable; // 是否顯示