个人项目作业
个人项目作业
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 班级链接 |
这个作业的要求在哪里 | 作业要求 |
我在这个课程的目标是 | 使用PSP完成一个能求解简单几何形状之间交点的控制台程序。 |
这个作业在哪个具体方面帮助我实现目标 | 回顾自己过去的生态方式,先了解自己,才能不断进步。 |
-
在文章开头给出教学班级和可克隆的 Github 项目地址(例子如下)。(1')
-
在开始实现程序之前,在下述 PSP 表格记录下你估计将在程序的各个模块的开发上耗费的时间。(0.5')
-
解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。(3')
首先对题目进行分析,需求主要有以下部分:1. 读入图形、2. 保存图形、3. 进行计算、4. 返回结果。
输入和输出可以直接处理,重点需要思考用怎样的数据结构来处理直线和点,以及求交点的计算方法。
在数据结构方面,考虑到直接使用vector来保存直线。
在求解交点方面,我考虑到之前的数学经验,先把交点式转化为一般式,然后通过两条直线联立求解即可求出交点。在这个过程中还需要考虑交点的重合,直线的平行几种情况。
此处还需要考虑如何安排求交点的顺序。
- 如果直接两两求交点,复杂度为\(O(n^2)\)
- 如果把求解过的直线不再计算,可以把计算量减半,但复杂度仍然为\(O(n^2)\)
最终我采取的是第二种方法。
-
设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的?(4')
有三个类分别为:
- Intersect,
- IntersectPoint
- Line
- Circle
Intersect是最外层的逻辑,包括了两个Vector的容器分别保存Cirlce,Line,一个Set容器保存交点。
包含三个方法
- addLine
- intersect
- intersect2circles
- intersect2line
- intersectLine2circle
程序的运行流程为,在main函数中按照规定次数执行addLine,完成添加后统一对每两条线求交点。在计算出每个交点后判断是否有重复的交点。单元测试只保留对addLine和intersect的测试。先添加一定的直线,再求出交点,验证答案。
流程图:
单元测试:
考虑到只有圆和直线相交情况分为以下几类:
直线与直线:
- 相交
- 平行
直线和圆:
- 相交
- 相切
- 不相交
圆和圆:
- 相交
- 相切
- 不相交
考虑到在程序中会对焦点去重处理所以不用考虑相切的情况
-
记录在改进程序性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由 VS 2019 的性能分析工具自动生成),并展示你程序中消耗最大的函数。(3')
改进思路:
-
在添加直线对时候直接计算直线的斜率和截距
- 使用set来保存交点,减少去重的计算量
- 去掉了异常处理提升性能
- 在便利的时候提前计算出图形
-
消耗最大的函数:
void Intersect::intersect2lines(Line line1, Line line2)
{
double k1, b1, k2, b2, x, y;
k1 = line1.k;
b1 = line1.b;
k2 = line2.k;
b2 = line2.b;
if (k1 == k2) {
return;
}
IntersectPoint *intersectpoint = new IntersectPoint();
if (isinf(k1) && isinf(k2)) {
return;
}
else if (isinf(k1)) {
x = line1.x1;
y = k2 * x + b2;
}
else if (isinf(k2)) {
x = line2.x1;
y = k1 * x + b1;
}
else {
x = -(b1 - b2) / (k1 - k2);
if (isnan(x) || isinf(x)) {
return;
}
else {
y = k1 * x + b1;
}
}
intersectpoint->x = x;
intersectpoint->y = y;
addIntersectPoint(*intersectpoint);
return;
}
-
代码说明。展示出项目关键代码,并解释思路与注释说明。(3')
由于我把主要计算函数都放在主类中,其余类比较简单。
Line类:主要保存了直线的两个定义点,和直线的斜率和截距
class Line { public: int x1; int x2; int y1; int y2; double k; double b; };
IntersectPoint类:保存交点的坐标
class IntersectPoint { public: double x = 0; double y = 0; };
Intersect类:主要完成数据的组织保存工作
class Intersect { private: vector<Line> lines; set<pair<double, double>> intersectpoints; public: void addLine(int x1, int y1, int x2, int y2); void intersect2lines(Line line1, Line line2); void addIntersectPoint(IntersectPoint intersectpoint); int intersect(); };
-
在你实现完程序之后,在下述 PSP 表格记录下你在程序的各个模块上实际花费的时间。(0.5')
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
· Estimate | · 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | ||
· Analysis | · 需求分析 (包括学习新技术) | 30 | 150 |
· Design Spec | · 生成设计文档 | 10 | 20 |
· Design Review | · 设计复审 (和同事审核设计文档) | 5 | 5 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 20 |
· Design | · 具体设计 | 20 | 40 |
· Coding | · 具体编码 | 90 | 350 |
· Code Review | · 代码复审 | 20 | 100 |
· Test | · 测试(自我测试,修改代码,提交修改) | 20 | 120 |
Reporting | 报告 | ||
· Test Report | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 5 | 5 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 10 | 30 |
合计 | 260 | 890 |
本此项目收获
- 对c++项目编程的流程能够熟悉
- 对单元测试有一定体验
- 对通过性能检测器分析程序优化