# voronoi diagram > 張恩維 ## 軟體規格書 * 輸入 1. 滑鼠在畫布上任意點擊,畫布大小為603*603 2. 輸入x軸及y軸座標 3. 隨機產生數個點 4. 讀入「輸入文字檔」 5. 讀入「輸出文字檔」,直接在畫布繪出圖形 * 輸出 1. 按下Save,輸出「輸出文字檔」 2. 輸出文字檔格式如下: 3. 輸入的座標點:P x y // 每個點佔一行,兩整數 x, y 為座標。 線段:E x1 y1 x2 y2 // (x1, y1) 為起點,(x2, y2) 為終點,其中 x1≦x2 或 x1=x2, y1≦y2 4. 座標點排列在前半段,線段排列在後半段。 5. 座標點以 lexical order順序排列(即先排序第一維座標,若相同,則再排序第二維座標;線段亦以lexical order順序排列。 ### 功能規格與介面規格 #### 主畫面  #### 功能介紹 * Read Data : 輸入檔案 * Run : 開始執行 * Save : 輸出檔案 * Next set : 下一筆測資 * Clean : 清除畫布 * step by step : 執行下一步 ## 軟體說明 ### 安裝說明 下載後直接執行exe檔即可。 ### 使用說明 * 提供兩種方法輸入 1. 直接在畫布上利用滑鼠點擊 2. 以符合輸入規範的檔案(.txt)當作輸入 * 以兩種方式繪製 1. 按下"run"按鈕,一次畫完diagram. 2. 按下"step by step"按鈕,直到畫完diagram.   * 提供一種方式輸出 1. 按下save,輸出.txt檔  ## 程式設計 ### 資料結構  ↑用於divide and conquer時  ↑存點的結構  ↑存邊的結構  ↑hyperplane的結構 ### 三點以下 利用重心公式,(a+b+c)/3,而重心一定在三角形的內部,在利用重心到各點的向量進行逆時針的排序,這樣一來可以確定法向量一定是朝外射出,接著再找到到三角形的外心,再由外心向法向量的方向畫出即可完成。在特別注意一下三點共線的情空即可。  ### 四點 ``` def voronoi(pointList): pointList.sort(key = attrgetter('x', 'y')) # 先對 x 排序在對 y 排序 if(len(pointList) == 1 ): return elif(len(pointList) == 2): result = two_point(pointList) else: p_left , p_right = divide(pointList) v_left = voronoi(p_left) # 得到 左邊的voronoi diagram v_right = voronoi(p_right) # 得到 右邊的voronoi diagram result = merge(v_left, v_right) #合併整個 voronoi diagram return result # return 整個voronoi diagram ``` * Divide 其實就先將座標點先依X軸再依Y軸排序後,在將一半的的點分給左邊和右邊, 之後在以遞迴的方式下去作就可以了,中止條件是到兩個點後在兩點中間畫一條線。 * Merge 第一步要做的就是找出上切線及下切線,作為下一步找Hyper Plane 的進入點及離開點。而切線的找法就是畫出整個的Convex Hull,然後逐一掃瞄Convex Hull上鄰近的兩個點,當兩個點分別屬於左右半部的點,該線段即為我們要找的切線。而找Convex Hull 的演算法,是Andrew's Monotone Chain找到上凸包以及下凸包。在分別判斷merge後的voronoi diagram的點的convex hull分別位於在還沒merge之前兩邊凸包即可。  * Hyperplane hyperplane 就是將convex hull 左右兩邊的點找出來並一步一步的往下去找,如果以hyperplane 的中垂線撞到的的中垂線,則構成hyperplane的兩點更新為那兩點,直到所有點構成的convex hull 下切線 == hyperplane,diagram 完成。  ## 軟體測試與實驗結果 ### 執行環境 * 程式語言:python * 作業系統:windows 11  ### 實驗結果        ## 結論與心得 原本是想要用c++來寫的,但因為沒用過Qt4,所以改用難度教低的python完成。 ## 附錄 我的github 程式碼都在這 https://github.com/wayne9756/voronoi-diagram.git
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up