个人项目作业

个人项目作业

项目 内容
这个作业属于哪个课程 班级链接
这个作业的要求在哪里 作业要求
我在这个课程的目标是 使用PSP完成一个能求解简单几何形状之间交点的控制台程序。
这个作业在哪个具体方面帮助我实现目标 回顾自己过去的生态方式,先了解自己,才能不断进步。
  1. 在文章开头给出教学班级和可克隆的 Github 项目地址(例子如下)。(1')
  2. 在开始实现程序之前,在下述 PSP 表格记录下你估计将在程序的各个模块的开发上耗费的时间。(0.5')
  3. 解题思路描述。即刚开始拿到题目后,如何思考,如何找资料的过程。(3')

    首先对题目进行分析,需求主要有以下部分:1. 读入图形、2. 保存图形、3. 进行计算、4. 返回结果。

    输入和输出可以直接处理,重点需要思考用怎样的数据结构来处理直线和点,以及求交点的计算方法。

    在数据结构方面,考虑到直接使用vector来保存直线。

    在求解交点方面,我考虑到之前的数学经验,先把交点式转化为一般式,然后通过两条直线联立求解即可求出交点。在这个过程中还需要考虑交点的重合,直线的平行几种情况。

    此处还需要考虑如何安排求交点的顺序。

    1. 如果直接两两求交点,复杂度为\(O(n^2)\)
    2. 如果把求解过的直线不再计算,可以把计算量减半,但复杂度仍然为\(O(n^2)\)

    最终我采取的是第二种方法。

  4. 设计实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?单元测试是怎么设计的?(4')

    有三个类分别为:

    1. Intersect,
    2. IntersectPoint
    3. Line
    4. Circle

    Intersect是最外层的逻辑,包括了两个Vector的容器分别保存Cirlce,Line,一个Set容器保存交点。

    包含三个方法

    1. addLine
    2. intersect
    3. intersect2circles
    4. intersect2line
    5. intersectLine2circle

    程序的运行流程为,在main函数中按照规定次数执行addLine,完成添加后统一对每两条线求交点。在计算出每个交点后判断是否有重复的交点。单元测试只保留对addLine和intersect的测试。先添加一定的直线,再求出交点,验证答案。

    流程图:

单元测试:

考虑到只有圆和直线相交情况分为以下几类:

直线与直线:

  1. 相交
  2. 平行

直线和圆:

  1. 相交
  2. 相切
  3. 不相交

圆和圆:

  1. 相交
  2. 相切
  3. 不相交

考虑到在程序中会对焦点去重处理所以不用考虑相切的情况

  1. 记录在改进程序性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由 VS 2019 的性能分析工具自动生成),并展示你程序中消耗最大的函数。(3')

    改进思路:

    1. 在添加直线对时候直接计算直线的斜率和截距

      1. 使用set来保存交点,减少去重的计算量
      2. 去掉了异常处理提升性能
      3. 在便利的时候提前计算出图形


消耗最大的函数:

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;
}
  1. 代码说明。展示出项目关键代码,并解释思路与注释说明。(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();
    };
    
  2. 在你实现完程序之后,在下述 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
本此项目收获
  1. 对c++项目编程的流程能够熟悉
  2. 对单元测试有一定体验
  3. 对通过性能检测器分析程序优化

posted on 2020-03-10 17:30  hjh3407  阅读(173)  评论(2编辑  收藏  举报

导航