太爽了
甚至还现学了叉积判断线段是否相交和求面积的方法
先给出我的代码:
#include <iostream>
#include <vector>
#include <iomanip>
#include <cmath>
using namespace std;
//下面需要补充多个类的声明及实现代码
const double EPS = 1e-6;
struct Point{
double x, y;
Point(double x, double y):x(x), y(y){}
};
class Quadrilateral{
public:
Quadrilateral(){}
Quadrilateral(vector<Point> &vertices):p(vertices){}
double getArea();
double getPerimeter();
bool verify();
protected:
vector<Point> p;//四边形的四个顶点,从任一顶点出发按顺序存放
};
class Parallelogram:protected Quadrilateral{
public:
Parallelogram(){}
Parallelogram(vector<Point> &vertices){Quadrilateral::p = vertices;}
double getArea();
double getPerimeter();
bool verify();
};
class Rectangle:protected Parallelogram{
public:
Rectangle(){}
Rectangle(vector<Point> &vertices){Quadrilateral::p = vertices;}
double getArea();
double getPerimeter();
bool verify();
};
bool Quadrilateral::verify(){
{
double x1 = p[2].x - p[0].x, y1 = p[2].y - p[0].y;
double x2 = p[1].x - p[0].x, y2 = p[1].y - p[0].y;
double x3 = p[3].x - p[0].x, y3 = p[3].y - p[0].y;
if((x1 * y2 - x2 * y1) * (x1 * y3 - x3 * y1) >= 0) return false;
}
{
double x1 = p[3].x - p[1].x, y1 = p[3].y - p[1].y;
double x2 = p[0].x - p[1].x, y2 = p[0].y - p[1].y;
double x3 = p[2].x - p[1].x, y3 = p[2].y - p[1].y;
if((x1 * y2 - x2 * y1) * (x1 * y3 - x3 * y1) >= 0) return false;
}
return true;
}
double Quadrilateral::getArea(){
if(verify()){
double S1 = 0.5 * fabs((p[1].x - p[0].x) * (p[2].y - p[0].y) - (p[1].y - p[0].y) * (p[2].x - p[0].x));
double S2 = 0.5 * fabs((p[3].x - p[0].x) * (p[2].y - p[0].y) - (p[3].y - p[0].y) * (p[2].x - p[0].x));
return S1 + S2;
}
else return 0.0;
}
double Quadrilateral::getPerimeter(){
if(verify()){
double l1 = sqrt(pow(p[1].x - p[0].x, 2.0) + pow(p[1].y - p[0].y, 2.0));
double l2 = sqrt(pow(p[2].x - p[1].x, 2.0) + pow(p[2].y - p[1].y, 2.0));
double l3 = sqrt(pow(p[3].x - p[2].x, 2.0) + pow(p[3].y - p[2].y, 2.0));
double l4 = sqrt(pow(p[0].x - p[3].x, 2.0) + pow(p[0].y - p[3].y, 2.0));
return l1 + l2 + l3 + l4;
}
else return 0.0;
}
bool Parallelogram::verify(){
if(Quadrilateral::verify()){
double l1 = sqrt(pow(p[1].x - p[0].x, 2.0) + pow(p[1].y - p[0].y, 2.0));
double l2 = sqrt(pow(p[2].x - p[1].x, 2.0) + pow(p[2].y - p[1].y, 2.0));
double l3 = sqrt(pow(p[3].x - p[2].x, 2.0) + pow(p[3].y - p[2].y, 2.0));
double l4 = sqrt(pow(p[0].x - p[3].x, 2.0) + pow(p[0].y - p[3].y, 2.0));
if(fabs(l1 - l3) <= EPS && fabs(l2 - l4) <= EPS) return true;
else return false;
}
else return false;
}
double Parallelogram::getArea(){
if(verify()) return Quadrilateral::getArea();
else return 0.0;
}
double Parallelogram::getPerimeter(){
if(verify()) return Quadrilateral::getPerimeter();
else return 0.0;
}
bool Rectangle::verify(){
if(Parallelogram::verify()){
double l1 = sqrt(pow(p[2].x - p[0].x, 2.0) + pow(p[2].y - p[0].y, 2.0));
double l2 = sqrt(pow(p[3].x - p[1].x, 2.0) + pow(p[3].y - p[1].y, 2.0));
if(fabs(l1 - l2) <= EPS) return true;
else return false;
}
else return false;
}
double Rectangle::getArea(){
if(verify()) return Quadrilateral::getArea();
else return 0.0;
}
double Rectangle::getPerimeter(){
if(verify()) return Quadrilateral::getPerimeter();
else return 0.0;
}
//填空结束
int main()
{
vector<Point> vertices;
for (int i=0;i<4;i++){
double x,y;
cin>>x>>y;
Point p(x,y);
vertices.push_back(p);
}
Quadrilateral q(vertices);
Parallelogram pa(vertices);
Rectangle r(vertices);
cout<<fixed<<setprecision(2);
cout<<(q.verify()?1:0)<<endl;
cout<<q.getArea()<<endl;
cout<<q.getPerimeter()<<endl;
cout<<(pa.verify()?1:0)<<endl;
cout<<pa.getArea()<<endl;
cout<<pa.getPerimeter()<<endl;
cout<<(r.verify()?1:0)<<endl;
cout<<r.getArea()<<endl;
cout<<r.getPerimeter()<<endl;
return 0;
}
当然以上是老师给的原文件填上我的答案之后的,我填的地方有注释标注的,很明显
说实话第一次用继承,虽然上次有用过,但是没那么深入
代码还有可以改进的地方,像在求面积和周长的时候,可以用一个值记录,以及一个值记录是否判断过,避免重复判断