机器人足球仿真第二次作业

要求

用面向对象的思维设计相关类,从而实现直线与直线、直线与圆、直线与矩形的交点

思路

设计直线,圆,矩形的类,运用数学定义来判断是否有交点,并计算出交点的坐标。

代码示例:(使用 VS Code 运行)

/*file: robocup2d2cd.h
brief:各个类的定义:直线类,圆形类,矩形类*/

class MyCircle2D {
    public:
        MyCircle2D(double x, double y, double r);
        double getCirX();
        double getCirY();
        double getCirR();
    private:
        double x;
        double y;  //圆心坐标
        double r;  //半径
};

class MyRectangle2D {
    public:
        MyRectangle2D(double xLeftB,
                  double yLeftB,
                  double xRightT,
                  double yRightT);
        double getRecXL();
        double getRecYL();
        double getRecXR();
        double getRecYR();
    private:
        double xLeftB;
        double yLeftB;
        double xRightT;
        double yRightT; //分别代表矩形左下角和右上角的坐标
};

class MyLine2D {
    public:
        MyLine2D(double a, double b, double c);
        void PointOfIntersection(MyLine2D &line);
        void PointOfIntersection(MyCircle2D &circle);
        void PointOfIntersection(MyRectangle2D &rectangle);//求交点
        double getLineA();
        double getLineB();
        double getLineC();
    private:
        double a;
        double b;
        double c;  //ax + by + c = 0;
};

/*file:robocup2d2cd.cpp
compiler: VS Code
function: 求直线与直线、直线与圆、直线与矩形的交点
*/
#include
#include
#include"robocup2d2cd.h"

using namespace std;

MyLine2D::MyLine2D(double a, double b, double c){
    this->a = a;
    this->b = b;
    this->c = c;
}

double MyLine2D::getLineA(){
    return this->a;
}

double MyLine2D::getLineB(){
    return this->b;
}

double MyLine2D::getLineC(){
    return this->c;
}

void MyLine2D::PointOfIntersection(MyLine2D &line){  //直线与另一条直线的交点
    if((this->a==0 && line.a==0) || (this->b==0 && line.b==0)){
        cout<<"wrong line!"<<endl;
    }
    if((this->a)*(line.b) != (this->b)*(line.a)){  //两直线相交
        cout<<"两直线相交,交点:("
            <<((this->b)*(line.c) - (this->c)*(line.b))/((this->a)*(line.b) - (this->b)*(line.a))
            <<","
            <<((this->c)*(line.a) - (this->a)*(line.c))/((this->a)*(line.b) - (this->b)*(line.a))
            <<")"<<endl;
    }else {  
        if(this->a!=0 && line.a!=0){
            if((this->a)/(line.a) == (this->c)/(line.c)) {
                cout<<"两直线重合,有无数交点"<<endl;
            }else {
                cout<<"两直线平行--无交点"<<endl;
            }
        }else if(this->b!=0 && line.b!=0){
            if((this->b)/(line.b) == (this->c)/(line.c)) {
                cout<<"两直线重合,有无数交点"<<endl;
            }else {
                cout<<"两直线平行,无交点"<<endl;
            }
        }
    }
}

void MyLine2D::PointOfIntersection(MyCircle2D &circle){
    if(this->a==0 && this->b==0){
            cout<<"wrong line!"<<endl;
    }
    double dist;  //圆心到直线的距离
    double k;
    double d;
    double f;
    dist = fabs((this->a)*(circle.getCirX()) + (this->b)*(circle.getCirY()) + this->c)
           /sqrt((this->a)*(this->a) + (this->b)*(this->b));
    if(this->b != 0){//斜率存在时,转化
        k = (-1)*this->a/this->b;
        d = (-1)*this->c/this->b;  //截距
        f = sqrt((k*k+1)*circle.getCirR()*circle.getCirR()
            - circle.getCirX()*circle.getCirX()*k*k
            + 2*k*(circle.getCirX()*circle.getCirY()+d*circle.getCirX())
            - circle.getCirY()*circle.getCirY()-2*d*circle.getCirY()-d*d);
    }
    if(dist == circle.getCirR()){
        cout<<"直线与圆相切,一个交点,交点:";
        if(this->a == 0){
            cout<<"("<<circle.getCirX()<<","<<(-1)*(this->c/this->b)<<")"<<endl;
        }else if(this->b == 0){
            cout<<"("<<(-1)*(this->c/this->a)<<","<<circle.getCirY()<<")"<<endl;
        }else {
            cout<<"("<<((-1)*f+(circle.getCirY()+d)*k+circle.getCirX())/(k*k+1)<<","
                <<((-1)*(k*(f+circle.getCirX())+circle.getCirY()*k*k-d)/(k*k+1))<<")"<<endl;
        }
    }else if(dist > circle.getCirR()){
        cout<<"直线与圆相离,无交点"<<endl;
    }else {
        cout<<"直线与圆相交,两个交点,交点:";
        double f1 = sqrt(circle.getCirR()*circle.getCirR()-(dist/2)*(dist/2));
        if(this->a == 0){
            cout<<"("<<circle.getCirX()-f1<<","<<d<<"),"
                <<"("<<circle.getCirX()+f1<<","<<d<<")"<<endl;
        }else if(this->b == 0){
            cout<<"("<<(-1)*this->c/this->a<<","<<circle.getCirY()-f1<<"),"
                <<"("<<(-1)*this->c/this->a<<","<<circle.getCirY()+f1<<")"<<endl;
        }else{
            cout<<"("<<((-1)*f+(circle.getCirY()+d)*k+circle.getCirX())/(k*k+1)<<","
                <<((-1)*(k*(f+circle.getCirX())+circle.getCirY()*k*k-d)/(k*k+1))<<")"
                <<","
                <<"("<<(f+(-1)*(circle.getCirY()+d)*k-circle.getCirX())/(k*k+1)<<","
                <<k*((f+(-1)*(circle.getCirY()+d)*k-circle.getCirX())/(k*k+1))+d<<")"<<endl; 
        }
    }
}

void MyLine2D::PointOfIntersection(MyRectangle2D &rec){
    if(this->a==0 && this->b==0){
            cout<<"wrong line!"<<endl;
    }
    //假设矩形的边平行于坐标轴
    double kRec;
    double bRec; //矩形对角线所在的直线的斜率,截距
    double kLine; //直线斜率存在时的斜率,截距
    double bLine;
    kRec = tan((rec.getRecYR()-rec.getRecYL())/(rec.getRecXR()-rec.getRecXL()));
    bRec = rec.getRecYL() - kRec*rec.getRecXL();

    if(this->b != 0){//直线斜率存在
        kLine = (-1)*this->a/this->b;
        bLine = (-1)*this->c/this->b;
        double y1 = kLine*rec.getRecXL()+bLine;
        double y2 = kLine*rec.getRecXR()+bLine;
        //矩形顶点到对角线的距离
        double dist = (rec.getRecXR()-rec.getRecXL())*(rec.getRecYR()-rec.getRecYL())
                    /sqrt((rec.getRecXR()-rec.getRecXL())*(rec.getRecXR()-rec.getRecXL())+
                    (rec.getRecYR()-rec.getRecYL())*(rec.getRecYR()-rec.getRecYL()));
        //矩形的左下角点到直线距离
        double dist1 = fabs(this->a*rec.getRecXL()+this->b*rec.getRecYL()+this->c)
                     /sqrt(this->a*this->a + this->b*this->b);
        //矩形的右上角点到直线距离
        double dist2 = fabs(this->a*rec.getRecXR()+this->b*rec.getRecYR()+this->c)
                     /sqrt(this->a*this->a + this->b*this->b);
        //对角线段(除去端点)与直线相交
        if((rec.getRecYL()<y1 && rec.getRecYR()>y2) || (rec.getRecYL()>y1 && rec.getRecYR()<y2)){
            cout<<"直线与矩形有两个交点:";
            if(kLine > 0){
                if(kLine > kRec){
                    cout<<"("<<(rec.getRecYL()-bLine)/kLine<<","<<rec.getRecYL()<<")"
                        <<"("<<(rec.getRecYR()-bLine)/kLine<<","<<rec.getRecYR()<<")"<<endl;
                }else {
                    cout<<"("<<rec.getRecXL()<<","<<kLine*rec.getRecXL()<<"),"
                        <<"("<<rec.getRecXR()<<","<<kLine*rec.getRecXR()<<")"<<endl;
                }
            }else if(kLine < 0){
                if(kLine*rec.getRecXR()+bLine > rec.getRecYL()){
                    if(kLine*rec.getRecXL()+bLine < rec.getRecYL()){
                        cout<<"("<<rec.getRecXL()<<","<<kLine*rec.getRecXL()<<"),"
                            <<"("<<rec.getRecXR()<<","<<kLine*rec.getRecXR()<<")"<<endl;
                    }else{
                        cout<<"("<<(rec.getRecYR()-bLine)/kLine<<","<<rec.getRecYR()<<")"
                            <<"("<<rec.getRecXR()<<","<<rec.getRecXR()*kLine+bLine<<")"<<endl;
                    }
                }else {
                    cout<<"("<<(rec.getRecYL()-bLine)/kLine<<","<<rec.getRecYL()<<")"
                        <<"("<<rec.getRecXL()<<","<<rec.getRecXL()*kLine+bLine<<")"<<endl;
                }
            }
        }else if(rec.getRecYL()<y1 && rec.getRecYR()<y2){//两点在直线的下方
            if(kLine*rec.getRecXL()+bLine > rec.getRecYR()){
                cout<<"直线与矩形没有交点"<<endl;
            }else if(kLine*rec.getRecXL()+bLine == rec.getRecYR()){
                cout<<"直线与矩形有一个交点:";
                cout<<"("<<rec.getRecXL()<<","<<rec.getRecYR()<<")"<<endl;
            }else {
                cout<<"直线与矩形有两个交点:";
                cout<<"("<<rec.getRecXL()<<","<<kLine*rec.getRecXL()+bLine<<"),"
                    <<"("<<(rec.getRecYR()-bLine)/kLine<<","<<rec.getRecYR()<<")"<<endl;
            }
        }else if(rec.getRecYL()>y1 && rec.getRecYR()>y2){//两点在直线的上方
            if(kLine*rec.getRecXR()+bLine < rec.getRecYL()){
                cout<<"直线与矩形没有交点"<<endl;
            }else if(kLine*rec.getRecXR()+bLine == rec.getRecYL()){
                cout<<"直线与矩形有一个交点:";
                cout<<"("<<rec.getRecXR()<<","<<rec.getRecYL()<<endl;
            }else {
                cout<<"直线与矩形有两个交点:";
                cout<<"("<<(rec.getRecYL()-bLine)/kLine<<","<<rec.getRecYL()<<"),"
                    <<"("<<rec.getRecXR()<<","<<kLine*rec.getRecXR()+bLine<<")"<<endl;
            }
        }
    }else{
        bLine = (-1)*this->a/this->c;
        if(bLine>rec.getRecXR() || bLine<rec.getRecXL()){
            cout<<"直线与矩形没有交点"<<endl;
        }else if(bLine<rec.getRecXR() || bLine>rec.getRecXL()){
            cout<<"直线与矩形有两个交点:";
            cout<<"("<<bLine<<","<<rec.getRecYL()<<"),"
                <<"("<<bLine<<","<<rec.getRecYR()<<")"<<endl;
        }else{
            cout<<"直线与矩形一条边重合,有无数交点"<<endl; 
        }
    }
}

MyCircle2D::MyCircle2D(double x, double y, double r){
    this->x = x;
    this->y = y;
    this->r = r;
}

double MyCircle2D::getCirX(){
    return this->x;
}

double MyCircle2D::getCirY(){
    return this->y;
}

double MyCircle2D::getCirR(){
    return this->r;
}

MyRectangle2D::MyRectangle2D(double x1, double y1,
                         double x2, double y2){
    this->xLeftB = x1;
    this->yLeftB = y1;
    this->xRightT = x2;
    this->yRightT = y2;
}

double MyRectangle2D::getRecXL(){
    return this->xLeftB;
}

double MyRectangle2D::getRecYL(){
    return this->yLeftB;
}

double MyRectangle2D::getRecXR(){
    return this->xRightT;
}

double MyRectangle2D::getRecYR(){
    return this->yRightT;
}

int main(){
    MyLine2D line1(2.0, 3.0, 1.0);
    MyLine2D line2(1.0, 4.0, 8.0);
    MyLine2D line3(4.0, -2.0, 3.0);
    MyLine2D line4(0.0, 3.0, 8.0);
    MyCircle2D circle(2.0, 2.0, 2.0);
    MyRectangle2D rec(-4.0, 0.0, 0.0, 3.0);
    line1.PointOfIntersection(line2);
    line1.PointOfIntersection(circle);
    line1.PointOfIntersection(rec);
    line2.PointOfIntersection(line3);
    line2.PointOfIntersection(circle);
    line2.PointOfIntersection(rec);
    line3.PointOfIntersection(line4);
    line3.PointOfIntersection(circle);
    line3.PointOfIntersection(rec);

    return 0;
}

运行结果示例:
机器人足球仿真第二次作业_第1张图片
PS:关于直线与矩形的交点问题并没有全面完整的解决。

你可能感兴趣的:(机器人足球仿真第二次作业)