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

it2025-03-15  25

要求

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

思路

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

代码示例:(使用 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<iostream> #include<math.h> #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; }

运行结果示例: PS:关于直线与矩形的交点问题并没有全面完整的解决。

最新回复(0)