实验目的:
【任务4】类的组合与继承
(1)先建立一个Point(点)类,包含数据成员x,y(坐标点);
(2)以Point为基类,派生出一个Circle(圆)类,增加数据成员(半径),基类的成员表示圆心;
(3)编写上述两类中的构造、析构函数及必要的输入输出函数
(4)定义友元函数int locate,判断点p在圆c上、圆c内或圆c外,返回值<0圆内,==0圆上,>0 圆外;
(5)重载关系运算符(6种)运算符,使之能够按圆的面积比较两个圆的大小;
(6)给定一点p,求出该点与圆心相连成的直线与圆的两个交点并输出
实验代码:
//自行定义类 //用下面的main()函数测试 #include <iostream> #include <cmath> using namespace std; class Point { public: Point(float xx, float yy) { x = xx; y = yy; } void show() { cout << "(" << x << ", " << y << ")" << endl; } friend ostream & operator << (ostream & output, Point & p) { p.show(); return output; } double distance(Point &p) { double dx = x - p.x; double dy = y - p.y; return sqrt(dx * dx + dy * dy); } double getx(){return x;} double gety(){return y;} void setx(double x1){x = x1;} void sety(double y1){y = y1;} ~Point(){} private: double x; double y; }; class Circle:public Point { public: Circle(float xx, float yy, float r):Point(xx, yy) { R = r; } double display() { Point::show(); cout << "半径为: "; return R; } friend ostream & operator << (ostream & output, Circle & c) { output << c.display() << endl; return output; } friend int locate(Point &p, Circle &c) { double d = c.distance(p); if(d - c.R > 0) return 1; else if(d < c.R) return -1; else return 0; } bool operator > (const Circle &); bool operator < (const Circle &); bool operator >= (const Circle &); bool operator <= (const Circle &); bool operator == (const Circle &); bool operator != (const Circle &); friend void crossover_point(Point &p1,Circle &c1, Point &p4,Point &p5); ~Circle(){} private: double R; }; bool Circle::operator > (const Circle &c) { return (R > c.R); } bool Circle::operator < (const Circle &c) { return (R < c.R); } bool Circle::operator >= (const Circle &c) { return (R >= c.R); } bool Circle::operator <= (const Circle &c) { return (R <= c.R); } bool Circle::operator == (const Circle &c) { return (R == c.R); } bool Circle::operator != (const Circle &c) { return (R != c.R); } void crossover_point(Point &p1,Circle &c1, Point &p4,Point &p5) { double x1 = p1.getx() - c1.getx(); double y1 = p1.gety() - c1.gety(); p4.setx((c1.R / c1.distance(p1) * x1) + c1.getx()); p4.sety((c1.R / c1.distance(p1) * y1) + c1.gety()); p5.setx(c1.getx() * 2 - p4.getx()); p5.sety(c1.gety() * 2 - p4.gety()); } int main( ) { Circle c1(3,2,4),c2(4,5,5); //c2应该大于c1 Point p1(1,1),p2(3,-2),p3(7,3); //分别位于c1内、上、外 cout <<"圆c1: " << c1; cout << "点p1: " << p1; cout << "点p1在圆c1之" << ((locate(p1, c1)>0)?"外":((locate(p1, c1)<0)?"内":"上")) << endl; cout << "点p2: " << p2; cout << "点p2在圆c1之" << ((locate(p2, c1)>0)?"外":((locate(p2, c1)<0)?"内":"上")) << endl; cout << "点p3: " << p3; cout << "点p3在圆c1之" << ((locate(p3, c1)>0)?"外":((locate(p3, c1)<0)?"内":"上")) << endl; cout << endl; cout << "圆c1: " << c1 << "的面积" << endl; if(c1 > c2) cout << "大于 "; if(c1 < c2) cout << "小于 "; if(c1 >= c2) cout << "大于等于 "; if(c1 <= c2) cout << "小于等于 "; if(c1 == c2) cout << "等于 "; if(c1 != c2) cout << "不等于 "; cout << endl; cout << "圆c2: " << c2 << "的面积" << endl; cout << endl; Point p4(1, 1) ,p5(1, 1); crossover_point(p1,c1, p4, p5); cout <<"点p1: " << p1; cout << "与圆c1: " << c1; cout << "的圆心相连,与圆交于两点,分别是:" << endl; cout << "交点: " << p4; cout << "交点: " << p5; cout << endl; system("pause"); return 0; }
实验结果截图:
圆c1: (3, 2) 半径为: 4 点p1: (1, 1) 点p1在圆c1之内 点p2: (3, -2) 点p2在圆c1之上 点p3: (7, 3) 点p3在圆c1之外 圆c1: (3, 2) 半径为: 4 的面积 小于 小于等于 不等于 圆c2: (4, 5) 半径为: 5 的面积 点p1: (1, 1) 与圆c1: (3, 2) 半径为: 4 的圆心相连,与圆交于两点,分别是: 交点: (-0.577709, 0.211146) 交点: (6.57771, 3.78885) 请按任意键继续. . .
实验心得:
我的天啊,真的是一个挺复杂,又挺有难度的问题啊,老师也是够“坏”的,前面的三小问不忘先让我们吃点甜头,我个人啊,真的是让这个程序纠结死了。本以为星期一已经完成的有一半了,天晓得,我太“自信”了,今天晚上用了得有三个小时完成我在以为是的“另一半”,难点从第四小问,接踵而至,唯一可以庆幸的是老师给了主函数,里边有locate()函数的大体形式,当然,在实现上也是让我煞费苦心啊,虽然只是比较两点之间的距离和半径大小的小问题,真的是有点绊到我了。
呵呵,只是,好戏才刚刚上演,嗯,第五小问还好,运载符的重载,比较面积也只需要比较半径就好了,第六小问就来大问题喽,我了个去,“给定一点p,求出该点与圆心相连成的直线与圆的两个交点并输出”,看着悲催的问题,在一整疯狂的郁闷之后,我用到了两个现在看来十分高深的数学思想,其一、相似三角形,就为了求其中的那一个可恶的焦点,之后,其二,用到了,两点的中点公式,虽然当年看来是很小儿科的东西,可是现在能想起来真的不容易啊!!!!!
综上所述:郁闷的问题,郁闷的过程,郁闷的·····