PlaneFighure.cpp

PlaneFigure-平面图形类
#include <iostream>
#include <cmath>
using namespace std;
constexpr double Pi=M_PI;
template <class T>
class point {
public:
    T x,y;
public:
    point():x(0),y(0) {}
    point(T x,T y):x(x),y(y) {}
    T getX() const {return x;}
    // 获取y坐标的函数
    T getY() const {return y;}
    friend ostream & operator<<(ostream & out, const point & p){out<<"("<<p.x<<","<<p.y<<")"; return out;}
    friend istream & operator>>(istream & in, point & p ){in>>p.x>>p.y; return in;}
    friend point operator+(const point & x, const point & y){return point(x.x+y.x,x.y+y.y);}
    friend point operator-(const point & x, const point & y){return point(x.x-y.x,x.y-y.y);}
    double abs(){return sqrt(x*x+y*y);}
    friend double dis(const point & x, const point & y){return sqrt((x-y).abs());}
};
template <class T>
class PlaneFigure {
public:
    virtual ~PlaneFigure() = default;
    virtual double S() const = 0;
    virtual double C() const = 0;
    virtual bool isInside(const point<T> &point) const {
        return false;
    }
    virtual bool isIntersect(const PlaneFigure<T> &other) const {
        return false;
    }
};
template <class T>
class circle:virtual public point<T>, virtual PlaneFigure<T> {
private:
    T r;
public:
    circle():r(0){}
    circle(T x,T y,T r):point<T>(x,y),r(r){}
    friend ostream & operator<<(ostream & out, const circle & o){out<<"{O:"<<point<T>(o)<<",r="<<o.r<<"}"; return out;}
    bool isIntersect(const circle & o) {
        cout << r - o.r << "-" << dis(*this, o) << "-" << r + o.r << " ";
        return dis(*this, o) < r + o.r && dis(*this, o) > r - o.r;
    }
    bool isInside(const point<T> & p) {
        return dis(*this, p) < r;
    }
    double S() const override {
        return Pi * r * r;
    }
    double C() const override {
        return 2 * Pi * r;
    }
    void draw() const {
        // 获取圆心坐标
        T xCenter = this->x;
        T yCenter = this->y;

        // 确定绘制圆形的范围边界,这里适当扩大范围以保证圆形完整显示
        T xMin = static_cast<T>(xCenter - r - 1);
        T xMax = static_cast<T>(xCenter + r + 1);
        T yMin = static_cast<T>(yCenter - r - 1);
        T yMax = static_cast<T>(yCenter + r + 1);

        for (T y = yMin; y <= yMax; ++y) {
            string row = "";
            T x = xMin;
            int count=0;
            for (x; x <= xMax; ++x) {
                if (sqrt((x - xCenter) * (x - xCenter) + (y - yCenter) * (y - yCenter)) <= r + 1e-9) {
                    row += "*";
                    count++;
                } else {
                    row += " ";
                }
            }
            cout << row;
            if (y==xCenter) {
                cout<<*this;
            }
            cout<< endl;
        }
    }
};

template <class T>
class rectangle : virtual public point<T>, virtual public PlaneFigure<T> {
private:
    T width;
    T height;
    point<T> rightTop;  // 右上角顶点
    point<T> leftBottom;  // 左下角顶点
    point<T> rightBottom;  // 右下角顶点
public:
    rectangle() : width(0), height(0) {}
    rectangle(T x, T y, T width, T height) : point<T>(x, y), width(width), height(height) {updateVertices();}
    void updateVertices() {
        rightTop.x = this->x + width;
        rightTop.y = this->y;
        leftBottom.x = this->x;
        leftBottom.y = this->y + height;
        rightBottom.x = this->x + width;
        rightBottom.y = this->y + height;
    }
    friend ostream & operator<<(ostream & out, const rectangle & rect) {
        out << "{[]: " << point<T>(rect) << ", w: " << rect.width << ", h: " << rect.height << "}";
        return out;
    }

    
    bool isInside(const point<T> & p) const {
        // 计算点到四个顶点的距离
        double disToLeftTop = dis(p, *this);
        double disToRightTop = dis(p, rightTop);
        double disToLeftBottom = dis(p, leftBottom);
        double disToRightBottom = dis(p, rightBottom);

        // 利用距离和矩形边长关系判断点是否在矩形内
        // 判断点到左上角顶点和右上角顶点的距离之和是否等于矩形的宽度
        bool widthCondition = (disToLeftTop + disToRightTop) >= abs(width) && (disToLeftTop + disToRightTop) <= abs(width) + 1e-9;
        // 判断点到左上角顶点和左下角顶点的距离之和是否等于矩形的高度
        bool heightCondition = (disToLeftTop + disToLeftBottom) >= abs(height) && (disToLeftTop + disToLeftBottom) <= abs(height) + 1e-9;

        return widthCondition && heightCondition;
    }

    
    bool isIntersect(const rectangle & other) const {
        return (this->x < other.x + other.width && this->x + width > other.x &&
                this->y < other.y + other.height && this->y + height > other.y);
    }

    double S() const override {
        return width * height;
    }

    
    double C() const override {
        return 2 * (width + height);
    }
    void draw() const {
        // 绘制矩形的上边框
        string topBorder = "^";
        string line="~~";
        string pline="";
        for (T i = 0; i < width; i++) {
            topBorder += line;
            pline += "  ";
        }
        topBorder += "^";
        // 输出第一行,包含左上角坐标和上边框
        cout << point<T>(*this)<< pline <<rightTop<< endl;
        cout<<"    "<<topBorder<<endl;
        // 绘制矩形的中间部分(除了上下边框)
        for (T i = 0; i < height; i++) {
            string middleRow = "    [";
            for (T j = 0; j < width ; j++) {
                middleRow += "**";
            }
            middleRow += "]";
            cout << middleRow << endl;
        }


        // 输出最后一行,包含下边框和右下角坐标
        cout<<"    "<<topBorder<<endl;
        cout <<leftBottom<< pline << rightBottom<< endl;
    }
};
template <class T>
void test(T a,T b) {
    cout<<a<<endl<<b<<endl;
    cout<<((a.isIntersect(b))?"yes":"no")<<endl;
}
int main() {
    circle<double>a(0,0,20),b(3,4,0.5);
    rectangle<double>c(0,0,5,5),d(3,4,0.5,0.5);
    test(a,b);
    test(c,d);
    a.draw();
    c.draw();
}

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部