work2_求交點數

教學班級:週三上午三四節
項目地址:https://github.com/875571216/-git

PSP表格

psp2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃 60 30
Estimate 估計這個任務須要多少時間 10 10
Development 開發
Analysis 需求分析 (包括學習新技術) 180 240
Design Spec 生成設計文檔 30 10
Design Review 設計複審 10 10
Coding Standard 代碼規範 (爲目前的開發制定合適的規範) 10 10
Design 具體設計 50 50
Coding 具體編碼 180 120
Code Review 代碼複審 10 10
Test 測試(自我測試,修改代碼,提交修改) 180 220
Reporting 報告 10 10
test Reporting 測試報告 30 20
Size Measurement 計算工做量 10 10
Postmortem & Process Improvement Plan 過後總結, 並提出過程改進計劃 10 10

解題思路描述

1)首先把輸入文件中的直線,圓的信息都構形成相應的對象,存入到各自的容器中。(直線、圓和點各設置一個動態數組容器vector來存儲)
2)交點分爲:直線與直線相交;直線與圓相交;圓與圓相交,在各自的類中設置求交點的成員方法。具體求法爲:
<1> 直線l1與直線l2:聯立解方程
<2> 直線l與圓c:求出一條通過圓c的圓心且與直線l垂直的直線_l,l與_l的交點是c的圓心做l的垂線的垂足,經過這個垂足能夠求出兩個交點。
<3> 圓c1與圓c2:兩圓的方程相減到它們焦點所在的直線,而後求直線與圓的交點。
3)交點加入加點集合(查重的方法是暴力遍歷,若是這個點在數組中已經存在,就不加入集合,沒找到更好的方法)github

設計實現過程。

1)代碼如何組織:
<1> 頭文件:定義了line(直線)、dot(點)、cycle(圓)三個數據類型。
<2> 主體cpp文件:引用了頭文件的三個數據類型。定義了line(直線)類中的「兩直線求交點」的方法。定義了cycle(圓)類中「兩圓求交點」的方法以及「圓與直線求交點」的方法。最後還有從文件讀入圓與直線信息並構造相應數據類型的的main函數。
<3> 單元測試:設置了10組單元測試,引用了頭文件中的三個數據類型,這三個數據類型的具體成員方法在主體cpp文件中定義好了。
2)單元測試:
<1> 直線與直線相交;
<2> 直線與直線平行;
<3> 圓與圓相離;
<4> 圓與圓外切;
<5> 圓與圓相交;
<6> 圓與圓內切;
<7> 圓包含圓;
<8> 直線與圓相離;
<9> 直線與圓相切;
<10> 直線與圓相交;數組

性能分析


能夠看到,個人程序中,佔用cpu最多的是solve,這個函數是我用來封裝計算全部交點的函數,佔用率高很正常。而後就是lintersectl這個函數,這個是用來計算直線交點的,因爲個人測試樣例只計算了直線與直線相交,這也比正常。有問題的是dotinsert這個函數,這個函數是用來插入點的,爲何會佔用這麼多的cpu呢,由於個人設計,是經過比較點的座標來判斷該點是否已經加入了交點集。我存儲交點的數據結構是一個數組,這就致使沒插入一個點就必須遍歷一邊數組,佔用大量的cpu資源。看圖:

個人改進辦法是用hash表來存儲交點,這樣每次插入點的複雜度就有o(n)變成了o(1),節省了大量的時間開銷。數據結構

關鍵代碼:

<1> 兩直線求交點方法:簡單解方程。

<2> 直線l與圓c求交點的方法:求出一條通過圓c的圓心且與直線l垂直的直線_l,l與_l的交點是c的圓心做l的垂線的垂足。而後經過點到直線距離公式求圓c的圓心到直線l的垂直距離d。用勾股定理就能算出垂足點到兩交點的距離,再結合直線l斜率,就能夠求出兩交點座標。固然,若是圓心到直線的垂直距離d大於圓半徑,那就沒有交點,相等則只有一個交點——垂足點。

<3> 兩圓相交:首先求出兩圓心之間的距離d,若是d>r1+r2(兩圓半徑之和)或者d+r1(較小圓的半徑)<r2,那麼兩個圓沒有交點。而後從兩個圓方程中解出經過他們交點的直線,再求直線與圓的交點

能夠看出,確實大部分時間都消耗在了遍歷數組上。因而,我決定用hash表來存儲交點集,這樣,在查找點集時的複雜度就有o(n)變爲o(1),節省了大量的時間開銷。函數

相關文章
相關標籤/搜索