天天看點

個人項目作業

個人項目作業

前言

項目 内容
這個作業屬于哪個課程 北航2020春軟工
這個作業的要求在哪裡
我在這個課程的目标是 學習并實踐軟體開發,提高團隊合作的能力
這個作業在哪個具體方面幫助我實作目标 個人開發實踐
我的教學班級 005
項目位址 https://github.com/zhyixuan/intersect

PSP表格

PSP2.1 Personal Software Process Stages 預估耗時(分鐘) 實際耗時(分鐘)
Planning 計劃
· Estimate · 估計這個任務需要多少時間 10
Development 開發
· Analysis · 需求分析 (包括學習新技術) 180 240
· Design Spec · 生成設計文檔 30
· Design Review · 設計複審 (和同僚稽核設計文檔) 20
· Coding Standard · 代碼規範 (為目前的開發制定合适的規範)
· Design · 具體設計 40
· Coding · 具體編碼 120 150
· Code Review · 代碼複審
· Test · 測試(自我測試,修改代碼,送出修改)
Reporting 報告
· Test Report · 測試報告
· Size Measurement · 計算工作量
· Postmortem & Process Improvement Plan · 事後總結, 并提出過程改進計劃
合計 620 560

問題:測試與改進工作沒有完全完成,對C++不熟悉,學習新技術占了一定的時間。

解題思路描述

  • 沒有想到其他辦法,是以采用了暴力求解。複雜度O(N2)。
    • 題目保證有限個交點,是以不會出現兩直線重合
    • 平行線間無交點。不平行的兩條直線必定相交于一點
  • 如何描述直線

    一般式都可以表達,是以選擇了一般式

    • 根據給定的兩點求直線

      先寫成兩點式:

      $\frac{y - y_2}{y_1- y_2} = \frac{x - x_2}{x_1- x_2} $。

      再化成一般式 $(y_1 - y_2)x + (x_2 -x_1)y + (x_1y_2 -x_2y_1) = 0$

      是以

      $$

      A = y_1 - y_2,B = x_2 -x_1,C =x_1y_2 -x_2y_1

  • 交點坐标公式

    首先判斷是否平行,平行則無交點

    • 平行的條件$A2B1-A1B2 =0$
    • 交點坐标

      x=\frac{C1B2-C2B1}{A1B2-A2B1},y =\frac{C1A2-C2A1}{A2B1-A1B2}

  • 如何保證精度
    • 使用double存儲,當兩個浮點數之差小于1e_15時,認為相等。

設計實作過程。設計包括代碼如何組織,比如會有幾個類,幾個函數,他們之間關系如何,關鍵函數是否需要畫出流程圖?單元測試是怎麼設計的?

    • 點類
      • x,y坐标
      • 兩點重合:x,y分别相等(浮點數的相等)
    • 直線類 A、B、C三個參數
  • 函數及其之間的關系
    • 主函數
      • 資料結構:vector來存儲直線。因為要求交點的個數,是以采用unordered_set來存儲交點。便于去重。
      • 流程。比較簡單,不再畫出流程圖,下面簡述流程。

        首先讀取指令行參數,打開輸入檔案依次讀取每一條直線并求解直線的A、B、C參數,将直線放入容器Vector中。

        周遊每兩條直線,如果二者不平行,則計算兩者交點,并加入set中。

    • 求直線交點

      周遊所有直線,求交點。将交點放入set中。當兩條直線已經不再比較的時候,放入

    • 重載unordered_set的相等方法,以判斷兩個交點是否為同一個。

代碼說明。展示出項目關鍵代碼,并解釋思路與注釋說明。

關鍵代碼:

Point類

class Point//一個點有x,y兩個坐标值
{
public:
	Point();
	Point(double x0, double y0);
	double x;
	double y;
};
           

直線類

class Line//直線的一般式為Ax+By+C=0.是以确定一條直線需要以下參數
{
public:
	Line(long long x1, long long y1, long long  x2, long long y2);
	long long A;
	long long B;
	long long C;

};
           

求直線的三個參數

//根據數學公式直接得出
A = y1 - y2;
B = x2 - x1;
C = x1 * y2 - x2 * y1;
           

計算兩直線的交點

//根據數學公式直接得出
x = (c1 * b2 - c2 * b1) / (a2 * b1 - a1 * b2);
y = (c1 * a2 - c2 * a1) / (a1 * b2 - a2 * b1);
           

判斷坐标點相等

const double EPS = 1e-15;
bool double_equal(double a, double b) {
	if (fabs(a - b) < EPS) {
		return true;
	}
	return false;
}
           

思路說明

​ 一條直線(一般式)應該具有3個參數(A,B,C),平面坐标系上的坐标點應該有兩個參數(x,y)。是以先構造兩個類用于存儲直線和點。

​ 使用vector儲存多條直線。在主函數中,每讀取到一條直線,就按照上面的方法計算出其參數A、B、C,并将這條直線放入vector數組中。

​ 在讀取完所有的直線後,周遊每兩條直線,當二者不平行時,用上述代碼求解交點,并将求出的交點放入存儲交點的一個unorder_set的集合中。(開始用的set,但是發現自己寫的重載operator不太對,是以換成了用unorder_set)

​ 最後将存儲交點的集合的大小輸出到output.txt即可。