# 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
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.