• 个人项目作业——交点检测


    个人项目作业——交点检测

    项目 内容
    这个作业属于哪个班级 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 中的所有警告:

  • 相关阅读:
    【程序员的实用工具推荐】 Mac 效率神器 Alfred
    【白话科普】《逆局》最终 boss 隐藏自己的方式是?
    自媒体时代的贤内助——AI 视频云
    MAC 连接 本机 mysql:MySQL said: Authentication plugin 'caching_sha2_password'
    普通微信支付最好用的库
    unicloud开发公众号
    关于微信unionid
    vueelementadmin二次开发 1
    vueelementadmin二次开发 2
    云桌面
  • 原文地址:https://www.cnblogs.com/spookydreamr/p/12457827.html
Copyright © 2020-2023  润新知