个人项目作业——交点检测
项目 | 内容 |
---|---|
这个作业属于哪个班级 | 2020春季计算机学院软件工程(罗杰 任健) |
这个作业的要求在哪里 | 个人项目作业 |
教学班级 | 005 |
GitHub项目地址 | https://github.com/SpookyDreamer/-intersect |
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 30 | 10 |
· Estimate | · 估计这个任务需要多少时间 | 10 | 10 |
Development | 开发 | 350 | 430 |
· Analysis | · 需求分析 (包括学习新技术) | 30 | 40 |
· Design Spec | · 生成设计文档 | 30 | 30 |
· Design Review | · 设计复审 (和同事审核设计文档) | 10 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
· Design | · 具体设计 | 60 | 40 |
· Coding | · 具体编码 | 60 | 90 |
· Code Review | · 代码复审 | 30 | 30 |
· Test | · 测试(自我测试,修改代码,提交修改) | 120 | 180 |
Reporting | 报告 | 160 | 130 |
· Test Report | · 测试报告 | 120 | 90 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 540 | 570 |
解题思路
基本要求
给定 N 条直线,询问平面中有多少个点在至少 2 条给定的直线上。题目输入保证答案只有有限个。
直线方程
直线方程共有五种形式:
-
一般式:Ax+By+C=0(AB≠0)
-
斜截式:y=kx+b(k是斜率b是x轴截距)
-
点斜式:y-y1=k(x-x1) (直线过定点(x1,y1))
-
两点式:(y-y1)/(x-x1)=(y-y2)/(x-x2) (直线过定点(x1,y1),(x2,y2))
-
截距式:x/a+y/b=1 (a是x轴截距,b是y轴截距)
由于本题输入描述直线时使用的是两个不重合的点的坐标,所以一开始我打算使用两点式表示直线,但是在实践过程中发现两点式在描述平行条件和求交点坐标时过于复杂,故采用在这两方面表达更加方便的一般式来表示直线方程。
给定两点坐标 (x1,y1),(x2,y2),直线方程的求法为:
[A=y2-y1
]
[B=x1-x2
]
[C=x2*y1-x1*y2
]
直线交点
给定两条直线:
[a1x+b1y+c1=0
]
[a2x+b2y+c2=0
]
首先,需要判断两条直线是否平行。两条直线平行的条件为:
[a1*b2=a2*b1
]
如果两直线平行,则两条直线没有交点。若两直线不平行,则交点坐标表示为:
[((b1*c2-b2*c1)/(a1*b2-a2*b1),(a2*c1-a1*c2)/(a1*b2-a2*b1))
]
设计实现过程
代码组织
一共设计了两个类,分别是Point类和Line类,其中Point类用于表示点,Line类用于表示直线。
class Point
{
private:
double x = 0;
double y = 0;
public:
Point(double xAxis, double yAxis);
virtual double getX();
virtual double getY();
virtual bool equals(Point *point);
};
class Line
{
private:
double A = 0;
double B = 0;
double C = 0;
public:
Line(Point *point1, Point *point2);
virtual bool isParallel(Line *line);
virtual Point *intersect(Line *line);
};
单元测试
在单元测试中,我对intersect
函数进行了测试,主要对以下方面等进行了测试:
- 小数据正整数
- 负数
- 正负数均包含
- 不为整数
- 较大的数据
- 边缘数据
此外,我还对isParallel函数进行了测试,用于检测是否能检测出两条平行的直线:
- 两条平行的直线
- 两条不平行的直线
测试结果如下所示:
性能分析
可以看出,消耗时间最多的部分是在使用unordered_set进行交点的插入时的Hash比较等方面。在这些地方是否有更好的方法来实现数据的比较和插入,在之后的改进中是值得思考的地方。
关键代码说明
求直线方程参数:
Line::Line(Point *point1, Point *point2)
{
A = point2->getY() - point1->getY();
B = point1->getX() - point2->getX();
const double tmp = point2->getX() * point1->getY();
C = tmp - point1->getX() * point2->getY();
}
判断两条直线是否平行:
bool Line::isParallel(Line *line)
{
return A * line->B == B * line->A;
}
求直线交点坐标:
Point *Line::intersect(Line *line)
{
//((b1*c2-b2*c1)/(a1*b2-a2*b1),(a2*c1-a1*c2)/(a1*b2-a2*b1))
double x = (B * line->C - line->B * C) / (A * line->B - line->A * B);
double y = (line->A * C- A * line->C)/(A * line->B- line->A * B);
Point *point = new Point(x, y);
return point;
}
其他说明
本项目已消除 Code Quality Analysis 中的所有警告: