EDITORIAL
プロジェクト | コンテンツ |
---|---|
保有しているコース | 春2020コンピュータソフトウェア工学研究所(ロジャー・レン建)(北) |
運用要件 | 個々のプロジェクトの作業 |
コースの目的 | ソフトウェア開発力の養成 |
仕事の目的を達成するために、この特定の役割 | 個人的な開発プロジェクトを行使できる能力 |
クラスを教えます | 006 |
githubのプロジェクトアドレス | https://github.com/LiuZH-19/SE_IntersectProject |
レコードにPSPフォーム
PSP2.1 | パーソナルソフトウェアプロセス段階 | 推定時間がかかる(分) | 実際の時間がかかる(分) |
---|---|---|---|
プランニング | 計画 | ||
・見積り | •このタスクが必要と推定どのくらいの時間 | 5 | 10 |
開発 | 開発 | ||
・分析 | (新しい技術を学ぶ含む)・ニーズ分析 | 180 | 220 |
・デザインスペック | 設計ドキュメントの生成 | 10 | 20 |
・デザインレビュー | ・デザインレビュー(と彼の同僚は、設計文書を見直し) | 15 | 20 |
・コーディング標準 | ・コードの仕様(現在の開発のための適切な規範の開発) | 5 | 5 |
・ 設計 | ・具体的な設計 | 30 | 60 |
・コーディング | ・具体的なコーディング | 120 | 160 |
・コードレビュー | ・コードレビュー | 20 | 20 |
・テスト | ・テスト(セルフテスト、コードを変更し、変更を提出) | 120 | 120 |
報告 | レポート | ||
・ 試験報告書 | ・テストレポート | 30 | 30 |
・サイズ測定 | ・コンピューティングのワークロード | 5 | 5 |
・死後&プロセス改善計画 | ・後知恵、およびプロセス改善計画を提案します | 10 | 30 |
トータル | 550 | 700 |
問題解決のためのアイデアの説明
一般的な考え方:
タイトルを読んだ後、方法があるのだと思います。
二つの直線L1、L2と式交差点その存在条件の交差の有無を解く数学的方法。
次に入力、判決のいずれか2つのラインのために。交差点がある場合、(容器内の反復エレメントを避けるために)容器に入れ
最後に、出力コンテナ内の交差点の数
しかし、線形入力二十から二複雑さを解決するための必要性を考慮すると、O($ N ^ 2 $)です。私はもっと巧妙なアルゴリズムがあるかどうかを確認するためにオンラインそれをルックアップするつもりです。
無駄にクエリ、およびビットを議論する小さなパートナー、何より良いアルゴリズムはありません。これは、このアルゴリズムによって意図され、細部について考えます。
直線のいくつかの特殊なケースを分析避けるために、私はラインに行きます一般式を表し:アックス+によって+ C = 0
追加の質問には、同様のアイデアです。
次いで、直線の交点を解くこと、および2つの円の交点のケースを解く前に、二つの直線両者の交点を解きます。
交差点を解決する前に、最初の決意状態を有する交差点は、不必要な計算を避けるために、満たされ
考慮すべき詳細:
彼は式の手の関係を働いたように、ラインの交点と行数は、より良いです。
直線と円の方程式手がカウントされます。
ラウンドと交差式の前のラウンドでは、自身がオンラインリファレンスアルゴリズムので、右のアウトカウントされないことを確認のため、私の大きな頭を解きます。見ます
設計と実装プロセス
コード組織:
当初は想定さ:
クラスの設計:
- ラインクラス
- = 0は、X1、Y1、X2、Y2の関数としてA、B、C直線アックス+により+ C、により表されます
- 属性A、B、C
- メンバ関数は、下駄()、getB()、getc関数()です
- Circleクラス
- $(XX)^ {2} +(YY)は^ {2} = R ^ 2 $表すの円
- X、Y、R属性
- メンバ関数はのgetX()、getY()表示、GETR()であります
- ラインクラス
直線の全てを格納するためのベクターで
すべての積集合を格納するために使用されるタイプのペア交差点
線と円との間のそれぞれの三つの機能は、二つの円の交点二つの直線、の間で計算されます。
上記のアイデアの実現によると、私は、直線と円クラスビットの冗長を発見しました。教科書にもと言っただけでデータパッケージ、あなたは構造体とクラスはありません。私は保存する構造を持つストレートと円形の引数であることを行っていますので。3つのケースが以前に計算クラスの関数としてパッケージ交点を計算しました。ことも考慮の計算における精度の損失問題、ポイント型の構成、オーバーライド演算子<。詳細は以下のとおりです。
その後の改良:
Calculatorクラスは
3つのメンバ関数をオーバーライドしますclass Calculator { public: Calculator(); int haveIntersection(Line l1, Line l2, set<Point>& nodeSet); int haveIntersection(Circle c, Line l, set<Point>& nodeSet); int haveIntersection(Circle c1, Circle c2, set<Point>& nodeSet); };
Pointクラス
にカスタマイズ演算子bool Point::operator < (const Point& p)const { //return x==p.x?y<p.y:x<p.x; return dcmp(x - p.x) == 0 ? dcmp(y - p.y) < 0 : dcmp(x - p.x) < 0; } bool Point::operator ==(const Point& p)const { if (dcmp(x-p.x)==0&&dcmp(y-p.y)==0) return true; return false; }
身体アーキテクチャの直線と円
関数countALLinsectメイン()
線と円と円との間の円の間の線との交点の場合は、計算されます
ユニットテストの設計
- 試験電卓クラスは、具体的には、以下の態様を含みます。
- 直線の交点ストレート
- パラレル
- 3行は1点で交わります
- x軸に平行な直線
- y軸に平行な直線
- 概して
- 直線と円の交点
- 直線の専用ケース
- ラウンドの関係を並べます
- 正接
- ウェイオフ
- 交差
- 交差点関係サークルとサークル
- ウェイオフ
- 交差
- エキソ
- 遠藤
- 含まれている(同心)
- 複雑な状況(二円及び直線)
- 交点があり、オーバーラップ
- 2つの交点があり、オーバーラップ
- 概して
- 直線の交点ストレート
- テストポイント型
検出オーバーライド演算子は<正しいです - 全体的にテスト
- データテスト、大量の、検出時間の質問の意味か
- 再セット検出するかどうか
テストは合格し、800万程度の交差点、7Sの時間、無タイムアウトとされている場合。
パフォーマンスの改善
図から分かるように、容器のセットの使用は、構築赤黒木は、CPU時間の大部分を占めます。プロセスにおける成果は、私は<オペレータ内部Pointクラスの書き換えを使用するので、経過時間が大きくなります。関連事業の外側のセットを削除し、私たちは電卓の次の機能に進みます。
どのCPU時間のほとんどは、まだ挿入操作のセットです占めています。だから私は、より最適なアルゴリズムの性能を向上させるために行うにはほとんどの仕事を考えることができませんでした。私はいくつかの一般的に使用される計算式は、後にダブルカウントを避けるために、動作するようになります。例えば、図:
すべての警告のコード品質分析を排除
用途は、スタイルの「Microsoftはそれを推奨しています」。
キーコード説明
すべてのケースの交点を解く:直線の前に、2つの直線とラウンド、ラウンド間
int countAllinsect(vector<Line> lVec, vector<Circle> cVec, set<Point> &nodeSet){ Calculator* calc = new Calculator(); size_t i, j; //计算两条直线间的交点 for (i = 0; i < lVec.size(); i++) { for (j = i + 1; j < lVec.size(); j++) { calc->haveIntersection(lVec[i], lVec[j], nodeSet); } } //计算直线与圆之间的交点 for (i = 0; i < cVec.size(); i++) { for (j = 0; j < lVec.size(); j++) { calc->haveIntersection(cVec[i], lVec[j], nodeSet); } } //计算两圆之间的交点 for (i = 0; i < cVec.size(); i++) { for (j = i + 1; j < cVec.size(); j++) { calc->haveIntersection(cVec[i], cVec[j], nodeSet); } } return nodeSet.size(); }
非常に暴力的な方法は、ループスルーにあります。
混乱
このプロジェクトは、単精度浮動小数点演算を必要とします。なぜなら除算と平方根の式、算出された最終点をもたらすことはちょうど約あります。私は比較関数を書き直したので、最終的に取るEPS 0.0000001です。一方でEPSは、私のテストを繰り返し選出された値の結果ですが、私は彼の有用性のいずれかのコースを保証することはできません。一致点かどうかを決定する場合したがって、誤りがあってもよいです。
ここでは、問題の精度に関連するコードは次のようになります。
#define EPS 0.0000001
int dcmp(double x) {
if (fabs(x) < EPS) return 0;
return x < 0 ? -1 : 1;
}
bool Point::operator < (const Point& p)const {
//return x==p.x?y<p.y:x<p.x;
return dcmp(x - p.x) == 0 ? dcmp(y - p.y) < 0 : dcmp(x - p.x) < 0;
}