(1)先建立一個Point(點)類,包含數據成員x,y(座標點);
(2)以Point爲基類,派生出一個Circle(圓)類,增加數據成員(半徑),基類的成員表示圓心;
(3)編寫上述兩類中的構造、析構函數及必要運算符重載函數(本項目主要是輸入輸出);
(4)定義友元函數int locate,判斷點p與圓的位置關係(返回值<0圓內,==0圓上,>0 圓外);
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;
return 0;
}
/*
* Copyright (c) 2015,煙臺大學計算機學院
* All right reserved.
* 作者:曹莉萍
* 文件:Demo.cpp
* 完成時間:2015年05月31日
* 版本號:v1.0
*/
#include <iostream>
#include<Cmath>
using namespace std;
class Point
{
public:
Point(double a=0,double b=0):x(a),y(b) {} //構造函數
double distance(const Point &p) const; //求距離
friend ostream & operator<<(ostream &,const Point &);//重載運算符“<<”
protected: //受保護成員
double x,y;
};
double Point::distance(const Point &p) const //求距離
{
double dx = x-p.x;
double dy = y-p.y;
return sqrt(dx*dx+dy*dy);
}
ostream & operator<<(ostream &output,const Point &p)
{
output<<"["<<p.x<<","<<p.y<<"]"<<endl;
return output;
}
class Circle:public Point //circle是Point類的公用派生類
{
public:
Circle(double a=0,double b=0,double r=0) :Point(a,b),radius(r) { }; //構造函數
friend ostream &operator<<(ostream &,const Circle &);//重載運算符“<<”
friend int locate(const Point &p, const Circle &c); //判斷點p在圓上、圓內或圓外,返回值:<0圓內,==0圓上,>0 圓外
protected:
double radius;
};
//重載運算符“<<”,使之按規定的形式輸出圓的信息
ostream &operator<<(ostream &output,const Circle &c)
{
output<<"Center=["<<c.x<<", "<<c.y<<"], r="<<c.radius<<endl;
return output;
}
//判斷點p在圓內、圓c內或圓c外
int locate(const Point &p, const Circle &c)
{
const Point cp(c.x,c.y); //圓心
double d = cp.distance(p);
if (abs(d - c.radius) < 1e-7)
return 0; //相等
else if (d < c.radius)
return -1; //圓內
else
return 1; //圓外
}
int main( )
{
Circle c1(3,2,4);
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;
return 0;
}
(5)在圓類上重載關係運算符(6種),使之能夠按圓的面積比較兩個圓的大小。自編main函數完成測試。
/*
* Copyright (c) 2015,煙臺大學計算機學院
* All right reserved.
* 作者:曹莉萍
* 文件:Demo.cpp
* 完成時間:2015年05月31日
* 版本號:v1.0
*/
#include <iostream>
#include<Cmath>
using namespace std;
class Point
{
public:
Point(double a=0,double b=0):x(a),y(b) {} //構造函數
protected: //受保護成員
double x,y;
};
class Circle:public Point //circle是Point類的公用派生類
{
public:
Circle(double a=0,double b=0,double r=0): Point(a,b),radius(r) { }//構造函數
double area ( ) const; //計算圓面積
friend ostream &operator<<(ostream &,const Circle &);//重載運算符“<<”
//重載關係運算符運算符,使之能夠按圓的面積比較兩個圓的大小;
bool operator>(const Circle &);
bool operator<(const Circle &);
bool operator>=(const Circle &);
bool operator<=(const Circle &);
bool operator==(const Circle &);
bool operator!=(const Circle &);
protected:
double radius;
};
//計算圓面積
double Circle::area( ) const
{
return 3.14159*radius*radius;
}
//重載運算符“<<”,使之按規定的形式輸出圓的信息
ostream &operator<<(ostream &output,const Circle &c)
{
output<<"Center=["<<c.x<<", "<<c.y<<"], r="<<c.radius;
return output;
}
//重載關係運算符(種)運算符,使之能夠按圓的面積比較兩個圓的大小;
bool Circle::operator>(const Circle &c)
{
return (this->radius - c.radius) > 1e-7;
}
bool Circle::operator<(const Circle &c)
{
return (c.radius - this->radius) > 1e-7;
}
bool Circle::operator>=(const Circle &c)
{
return !(*this < c);
}
bool Circle::operator<=(const Circle &c)
{
return !(*this > c);
}
bool Circle::operator==(const Circle &c)
{
return abs(this->radius - c.radius) < 1e-7;
}
bool Circle::operator!=(const Circle &c)
{
return abs(this->radius - c.radius) > 1e-7;
}
int main( )
{
Circle c1(3,2,4),c2(4,5,5); //c2應該大於c1
cout<<"圓c1( "<<c1<<" )的面積是 "<<c1.area()<<endl;
cout<<"圓c2( "<<c2<<" )的面積是 "<<c2.area()<<endl;
cout<<"圓c1 ";
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<<"圓c2"<<endl;
return 0;
}
6)與圓心相連的直線:給定一點p,其與圓心相連成的直線,會和圓有兩個交點,如圖。在上面定義的Point(點)類和Circle(圓)類基礎上,設計一種方案,輸出這兩點的座標。
方法1:用引用類型參數
/*
* Copyright (c) 2015,煙臺大學計算機學院
* All right reserved.
* 作者:曹莉萍
* 文件:Demo.cpp
* 完成時間:2015年05月31日
* 版本號:v1.0
*/
#include <iostream>
#include<Cmath>
using namespace std;
class Circle; //由於在Point中聲明友元函數crossover_point中參數中用了Circle,需要提前聲明
class Point
{
public:
Point(double a=0,double b=0):x(a),y(b) {} //構造函數
friend ostream & operator<<(ostream &,const Point &);//重載運算符“<<”
friend void crossover_point(Point &p,Circle &c, Point &p1,Point &p2 ) ; //求交點的友元函數
protected: //受保護成員
double x,y;
};
ostream & operator<<(ostream &output,const Point &p)
{
output<<"["<<p.x<<","<<p.y<<"]";
return output;
}
class Circle:public Point //circle是Point類的公用派生類
{
public:
Circle(double a=0,double b=0,double r=0):Point(a,b),radius(r) { } //構造函數
friend ostream &operator<<(ostream &,const Circle &);//重載運算符“<<”
friend void crossover_point(Point &p,Circle &c, Point &p1,Point &p2 ) ; //求交點的友元函數
protected:
double radius;
};
//重載運算符“<<”,使之按規定的形式輸出圓的信息
ostream &operator<<(ostream &output,const Circle &c)
{
output<<"Center=["<<c.x<<", "<<c.y<<"], r="<<c.radius;
return output;
}
//給定一點p,求出該點與圓c的圓心相連成的直線與圓的兩個交點p1和p2
//關鍵問題是求得的交點如何返回
//方案1:利用引用類型的形式參數,注意,下面的p1和p2將“帶回”求得的結果
//crossover_point函數已經聲明爲Point和Circle類的友元函數,類中私有成員可以直接訪問
void crossover_point(Point &p, Circle &c, Point &p1,Point &p2 )
{
p1.x = (c.x + sqrt(c.radius*c.radius/(1+((c.y-p.y)/(c.x-p.x))*((c.y-p.y)/(c.x-p.x)))));
p2.x = (c.x - sqrt(c.radius*c.radius/(1+((c.y-p.y)/(c.x-p.x))*((c.y-p.y)/(c.x-p.x)))));
p1.y = (p.y + (p1.x -p.x)*(c.y-p.y)/(c.x-p.x));
p2.y = (p.y + (p2.x -p.x)*(c.y-p.y)/(c.x-p.x));
}
int main( )
{
Circle c1(3,2,4);
Point p1(1,1),p2,p3;
crossover_point(p1,c1, p2, p3);
cout<<"點p1: "<<p1<<endl;
cout<<"與圓c1: "<<c1<<endl;
cout<<"的圓心相連,與圓交於兩點,分別是:"<<endl;
cout<<"交點1: "<<p2<<endl;
cout<<"交點2: "<<p3<<endl;
return 0;
}
方法2:結構體(定義兩個包含兩個點的結構體,用於返回值)
/*
* Copyright (c) 2015,煙臺大學計算機學院
* All right reserved.
* 作者:曹莉萍
* 文件:Demo.cpp
* 完成時間:2015年05月31日
* 版本號:v1.0
*/
#include <iostream>
#include<Cmath>
using namespace std;
class Circle; //由於在Point中聲明友元函數crossover_point中參數中用了Circle,需要提前聲明
struct DoublePoint; //也先聲明,Point中聲明友元函數crossover_point中要用到
class Point
{
public:
Point(double a=0,double b=0):x(a),y(b) {} //構造函數
friend ostream & operator<<(ostream &,const Point &);//重載運算符“<<”
friend DoublePoint crossover_point(Point &p,Circle &c) ; //求交點的友元函數
protected: //受保護成員
double x,y;
};
ostream & operator<<(ostream &output,const Point &p)
{
output<<"["<<p.x<<","<<p.y<<"]";
return output;
}
class Circle:public Point //circle是Point類的公用派生類
{
public:
Circle(double a=0,double b=0,double r=0):Point(a,b),radius(r) { } //構造函數
friend ostream &operator<<(ostream &,const Circle &);//重載運算符“<<”
friend DoublePoint crossover_point(Point &p,Circle &c) ; //求交點的友元函數
protected:
double radius;
};
//重載運算符“<<”,使之按規定的形式輸出圓的信息
ostream &operator<<(ostream &output,const Circle &c)
{
output<<"Center=["<<c.x<<", "<<c.y<<"], r="<<c.radius;
return output;
}
struct DoublePoint //專門用於返回值的結構體類型
{
Point p1;
Point p2;
};
//給定一點p,求出該點與圓c的圓心相連成的直線與圓的兩個交點
//方案2:結果返回到DoublePoint類型的結構體中
//crossover_point函數已經聲明爲Point和Circle類的友元函數,類中私有成員可以直接訪問
DoublePoint crossover_point(Point &p, Circle &c)
{
DoublePoint pp;
pp.p1.x = (c.x + sqrt(c.radius*c.radius/(1+((c.y-p.y)/(c.x-p.x))*((c.y-p.y)/(c.x-p.x)))));
pp.p2.x = (c.x - sqrt(c.radius*c.radius/(1+((c.y-p.y)/(c.x-p.x))*((c.y-p.y)/(c.x-p.x)))));
pp.p1.y = (p.y + (pp.p1.x -p.x)*(c.y-p.y)/(c.x-p.x));
pp.p2.y = (p.y + (pp.p2.x -p.x)*(c.y-p.y)/(c.x-p.x));
return pp;
}
int main( )
{
Circle c1(3,2,4);
Point p1(1,1);
DoublePoint pp;
pp = crossover_point(p1,c1);
cout<<"點p1: "<<p1<<endl;
cout<<"與圓c1: "<<c1<<endl;
cout<<"的圓心相連,與圓交於兩點,分別是:"<<endl;
cout<<"交點1: "<<pp.p1<<endl;
cout<<"交點2: "<<pp.p2<<endl;
return 0;
}
好複雜的項目4,千辛萬苦弄完以後竟然有種字符搬家的感覺。
趕快吸收爲自己的吧。
加油加油!