• 个人项目作业


    个人项目作业

    写在前面:

    项目 内容
    这个作业属于哪个课程 2020年春季计算机学院软件工程(罗杰 任建)
    这个作业的要求在哪里 个人项目作业
    教学班级 005
    项目Github链接 https://github.com/ame-lm/SEC_HW_IndividualProject

    项目PSP表格:

    PSP2.1 预估耗时(分钟) 实际耗时(分钟)
    Planning 60 60
    · Estimate 30 30
    Development 420 600
    · Analysis 20 20
    · Design Spec 20 20
    · Design Review 20 20
    · Coding Standard 20 20
    · Design 40 100
    · Coding 240 300
    · Code Review 30 60
    · Test 60 120
    Reporting 40 40
    · Test Report 20 20
    · Size Measurement 10 10
    · Postmortem & Process Improvement Plan 10 10

    解题思路

    按照直线和直线, 直线和圆, 圆和圆在平面上的关系分为下面三种情况考虑:

    直线和直线:

    1. 判断直线是否相交: (A_1*B_2-A_2*B_1!=0)则相交.
    2. 若相交则求交点: ((frac{B_1*C_2-B_2*C_1}{A_1*B_2-A_2*B_1},frac{A_2*C_1-A_1*C_2}{A_1*B_2-A_2*B_1}))

    直线和圆:

    1. 联立直线和圆方程(为了起见简便, 若(B!=0), 化为斜截式再联立), 求得系数(tA), (tB), (tC).
    2. 根据(Delta=tB^2-4*tA*tC)判断交点个数
    3. (Deltage0) , 根据求根公式求得交点横坐标, 进而求出交点.

    圆和圆:

    1. 计算圆心距(dis=sqrt{(x_1-x_2)^2+(y_1-y_2)^2}).
    2. 比较圆心距(dis) 和半径和(r_1+r_2), 半径差(|r_1-r_2|) .
    3. 若有交点则两圆相减求出相交弦方程, 进而转化为直线和圆得交点.

    程序设计

    对象建模:

    平面: Class PlaneContainer

    几何图形: Class Figure

    交点: Class Point

    直线: Class Line: Figure

    圆: Class Circle: Figure

    交互逻辑:

    Class Point重载<, ==以适应set模板.

    Class Figure子类均需实现set<Point> ClassName::intersect(Figure* figure)方法用于计算交点.

    Class PlaneContainer实现void PlaneContainer::insert(Figure* figure)方法用于添加Figure, 每次添加均需和平面内已有图形求交点.

    Class PlaneContainer每次添加Figure得到的点放入set<Point> intersectionPoints中, 借助set类型过滤相同点.

    单元测试

    分成两类测试:

    测试简单几何对象:

    TEST_METHOD(Test1) {//for Circle.cpp, Line.cpp, Figure.cpp, Point.cpp
    		Point* p1 = new Point(1, 0);
    		Point* p2 = new Point(100000, 0);
    		Point* p3 = new Point(1, -100000);
    		Point* p4 = new Point(-100000, 100000);
    		Assert::AreNotEqual((int)p1, NULL);
    		Assert::AreNotEqual((int)p2, NULL);
    		Assert::AreNotEqual((int)p3, NULL);
    		Assert::AreNotEqual((int)p4, NULL);
    
    		Circle* c1 = new Circle(0, 0, 1);
    		Circle* c2 = new Circle(-100000, 100000, 100000);
    		Assert::AreNotEqual((int)c1, NULL);
    		Assert::AreNotEqual((int)c2, NULL);
    
    		Line* l1 = new Line(0, 0, 1, 100000);
    		Line* l2 = new Line(100000, 0, 1, 100000);
    		Line* l3 = new Line(0, 0, -100000, 100000);
    		Line* l4 = new Line(0, -334, 1, 100000);
    		Assert::AreNotEqual((int)l1, NULL);
    		Assert::AreNotEqual((int)l2, NULL);
    		Assert::AreNotEqual((int)l3, NULL);
    		Assert::AreNotEqual((int)l4, NULL);
    	}
    

    测试几何对象在平面上相交情况:

    包括直线与圆相离, 相交, 相切等测试.

    TEST_METHOD(Test2) {//for PlaneContainer.cpp
    		//test for condition1: all objs are lines
    		PlaneContainer* pc1 = new PlaneContainer();
    		Assert::AreEqual(pc1->countIntersectionPoints(), 0);
    		Line* l1 = new Line(0, 1, 0);
    		pc1->insert(l1);
    		Assert::AreEqual(pc1->countIntersectionPoints(), 0);
    		Line* l2 = new Line(1, 0, 0);
    		pc1->insert(l2);
    		Assert::AreEqual(pc1->countIntersectionPoints(), 1);
    		Line* l3 = new Line(1, 1, 1);
    		pc1->insert(l3);
    		Assert::AreEqual(pc1->countIntersectionPoints(), 3);
    		Line* l4 = new Line(1, 1, -1);
    		pc1->insert(l4);
    		Assert::AreEqual(pc1->countIntersectionPoints(), 5);
    		Line* l5 = new Line(1, -1, 1);
    		pc1->insert(l5);
    		Assert::AreEqual(pc1->countIntersectionPoints(), 5);
    		Line* l6 = new Line(1, -1, -1);
    		pc1->insert(l6);
    		Assert::AreEqual(pc1->countIntersectionPoints(), 5);
    
    		//test for condition2: all objs are circles
    		PlaneContainer* pc2 = new PlaneContainer();
    		Assert::AreEqual(pc2->countIntersectionPoints(), 0);
    		Circle* c1 = new Circle(0, 0, 1);
    		pc2->insert(c1);
    		Assert::AreEqual(pc2->countIntersectionPoints(), 0);
    		Circle* c2 = new Circle(1, 0, 1);
    		pc2->insert(c2);
    		Assert::AreEqual(pc2->countIntersectionPoints(), 2);
    		Circle* c3 = new Circle(0, 1, 1);
    		pc2->insert(c3);
    		Assert::AreEqual(pc2->countIntersectionPoints(), 6);
    		Circle* c4 = new Circle(-1, 0, 1);
    		pc2->insert(c4);
    		Assert::AreEqual(pc2->countIntersectionPoints(), 9);
    		Circle* c5 = new Circle(0, -1, 1);
    		pc2->insert(c5);
    		Assert::AreEqual(pc2->countIntersectionPoints(), 13);
    		Circle* c6 = new Circle(0, 0, 2);
    		pc2->insert(c6);
    		Assert::AreEqual(pc2->countIntersectionPoints(), 17);
    
    		//test for condition3: objs contains lines and circles
    		PlaneContainer* pc3 = new PlaneContainer();
    		pc3->insert(l1);
    		pc3->insert(l2);
    		pc3->insert(l3);
    		pc3->insert(l4);
    		pc3->insert(l5);
    		pc3->insert(l6);
    		Assert::AreEqual(pc3->countIntersectionPoints(), 5);
    
    		pc3->insert(c1);
    		Assert::AreEqual(pc3->countIntersectionPoints(), 5 + 0);
    
    		pc3->insert(c2);
    		Assert::AreEqual(pc3->countIntersectionPoints(), 5 + 2 + 5);
    	}
    

    关键代码

    Class Line求解相交:

    set<Point> Line::intersect(Figure* figure) {
    	double x, y;
    	set<Point> points;
    	if (typeid(*figure) == typeid(Line)) {//line-line condition 
    		Line* line = (Line*)figure;
    		double A1, B1, C1, A2, B2, C2;
            //line1 cofficient 
    		A1 = this->A; B1 = this->B; C1 = this->C;
            //line2 cofficient 
    		A2 = line->getA(); B2 = line->getB(); C2 = line->getC();
    		//cordinate formula:((B1*C2-B2*C1)/(A1*B2-A2*B1),(A2*C1-A1*C2)/(A1*B2-A2*B1))
    		if (A1 * B2 != A2 * B1) {//not paralell
    			x = (B1 * C2 - B2 * C1) / (A1 * B2 - A2 * B1);
    			y = (A2 * C1 - A1 * C2) / (A1 * B2 - A2 * B1);
    			points.insert(Point(x, y));
    		}
    	} else if (typeid(*figure) == typeid(Circle)) {//line-circle condition 
    		Circle* circle = (Circle*)figure;
    		double tA, tB, tC, a, b, r, k, m, Delta;
            //circle cofficient
    		a = circle->getX();
    		b = circle->getY();
    		r = circle->getR();
    		if (B != 0) {//if line slope exists
                 //line slope and intercept
    			k = -A / B;
    			m = -C / B;
    			//body equation cofficients 
    			//tA=1+k^2
    			tA = 1 + k * k;
    			//tB=2(km-bk-a)
    			tB = 2 * (k * m - b * k - a);
    			//tC=a^2+(b-m)^2-r^2
    			tC = a * a + (b - m) * (b - m) - r * r;
                
    			Delta = tB * tB - 4 * tA * tC;
    			if (Delta > 0) {//intersection
    				x = (-tB + sqrt(Delta)) / (2 * tA);
    				y = k * x + m;
    				points.insert(Point(x, y));
    
    				x = (-tB - sqrt(Delta)) / (2 * tA);
    				y = k * x + m;
    				points.insert(Point(x, y));
    			} else if (Delta == 0) {//tangent
    				x = -tB / (2 * tA);
    				y = k * x + m;
    				points.insert(Point(x, y));
    			}
    		} else {//line slope not exists
    			x = m = -C / A;
    			y = b + sqrt(r * r - (m - a) * (m - a));
    			points.insert(Point(x, y));
    
    			y = b - sqrt(r * r - (m - a) * (m - a));
    			points.insert(Point(x, y));
    		}
    	}
    	return points;
    }
    

    Class Circle求解相交:

    set<Point> Circle::intersect(Figure* figure) {
    	double x, y;
    	set<Point> points;
    	if (typeid(*figure) == typeid(Line)) {
             //transform circle-line condition into line-circle conditon
    		Line* line = (Line*)figure;
    		points = line->intersect(this);
    	} else if (typeid(*figure) == typeid(Circle)) {
    		Circle* circle = (Circle*)figure;
    		double x1, x2, y1, y2, r1, r2;
    		double D1, D2, E1, E2, F1, F2, dis;
             //circle1 cofficient
    		x1 = this->x;
    		y1 = this->y;
    		r1 = this->r;
             //circle2 cofficient
    		x2 = circle->getX();
    		y2 = circle->getY();
    		r2 = circle->getR();
             //center distance
    		dis = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
    		dis = sqrt(dis);
             //normal formula of circle
    		D1 = -2 * x1;
    		E1 = -2 * y1;
    		F1 = x1 * x1 + y1 * y1 - r1 * r1;
    		D2 = -2 * x2;
    		E2 = -2 * y2;
    		F2 = x2 * x2 + y2 * y2 - r2 * r2;
    		if (dis <= r1 + r2 && dis >= abs(r1 - r2)) {
                 //quation about the intersection string and then transformed into line-circle condition
    			points = Line(D1 - D2, E1 - E2, F1 - F2).intersect(this);
    		}
    	}
    	return points;
    }
    
  • 相关阅读:
    计算机术语
    【转】 物理内存和线性空间
    windows Visual Studio 上安装 CUDA【转载】
    windows Notepad++ 上配置 vs 编译器 , 编译并运行
    单列模式 [转载]
    Java Swing布局管理器GridBagLayout的使用示例 [转]
    五年java工作应具备的技能
    三年java软件工程师应有的技技能
    京东面试题 Java相关
    京东笔试题总结
  • 原文地址:https://www.cnblogs.com/black-watch/p/12456849.html
Copyright © 2020-2023  润新知