一.需求分析
我们需要定义一个矩形类,属性有中心点坐标x,y和宽和高w,h,然后有一个判断函数,判断当前矩形和传进来的矩形是否相交.
二.思路
定义矩形类Rect,属性有两个结构体CPoint和HW,一个用来存中心点坐标x,y,一个用来存宽高w,h。
//点坐标
struct CPoint {
float x, y;
};
//宽高
struct HW {
float h, w;
};
还有初始化函数,当然也可以通过构造函数,这里用的是自定义的初始化函数
void Rect::Init(CPoint cp, HW hw) {
this->cp = cp;
//结构体中没有指针变量,可以直接拷贝,不建议使用。有指针成员需单独赋值。
this->hw = hw;
}
三.判断相交
最重要的是如何通过x,y,w,h来判断两个矩形是否相交
我们可以这样理解,通过两个矩形的中心点坐标来判断两矩形的相对位置
下面我们分情况一一讨论 两个矩形中心点 直接上代码,带有注释
//看两个点的相对位置分情况
//如果中心点重合必定相交
if (x1 == x2 && y1 == y2)return true;
//this在r1的右上角
else if (x1 > x2 && y1 > y2)k = 0;
//this在r1的左下角
else if (x1 < x2 && y1 < y2)k = 1;
//this在r1的左上角
else if (x1 < x2 && y1 > y2)k = 2;
//this在r1的右下角
else if (x1 > x2 && y1 < y2)k = 3;
//this和r1横坐标相等
else if (x1 == x2)k = 4;
//纵坐标相等
else if (y1 == y2)k = 5;
然后根据k的不同值来执行相应代码
//根据不同情况选择不同判断方式
//down1代表this的下边y值,up1代表上边y值,left1代表左边x值,right1代表右边x值
//2同理
//条件成立return true 注意画图了解,自己画图浅显易懂
switch (k) {
case 0:
if (down1 <= up2 && left1 <= right2)return true;
break;
case 1:
if (down2 <= up1 && left2 <= right1) return true;
break;
case 2:
if (down1 <= up2 && left2 <= right1)return true;
break;
case 3:
if (down2 <= up1 && left1 <= right2)return true;
break;
case 4:
if ((y1-y2>0?y1-y2:y2-y1)<=h1/2+h2/2)return true;
break;
case 5:
if ((x1 - x2 > 0 ? x1 - x2 : x2 - x1) <= w1 / 2 + w2 / 2)return true;
break;
default:
break;
}
return false;
四.运行结果
五.完整代码
#include<iostream>
using namespace std;
//点坐标
struct CPoint {
float x, y;
};
//宽高
struct HW {
float h, w;
};
class Rect {
public:
//初始化数据
void Init(CPoint cp, HW hw) {
this->cp = cp;
//结构体中没有指针变量,可以直接拷贝,不建议使用。有指针成员需单独赋值。
this->hw = hw;
}
//判断函数
bool judge(Rect r1) {
//x1,y1,h1,w1 分别对应 this的x,y,h,w。 r1同理
//this代表当前矩形,r1是传进来的矩形
float x1 = this->cp.x, y1 = this->cp.y, x2 = r1.cp.x, y2 = r1.cp.y,
h1 = this->hw.h, w1 = this->hw.w, h2 = r1.hw.h, w2 = r1.hw.w;
float left1 = x1 - w1 / 2, right1 = x1 + w1 / 2, left2 = x2 - w2 / 2, right2 = x2 + w2 / 2;
float down1 = y1 - h1 / 2, up1 = y1 + h1 / 2, down2 = y2 - h2 / 2, up2 = y2 + h2 / 2;
//6种情况
//两个矩形横纵坐标的所有情况
int k;
//看两个点的相对位置分情况
//如果中心点重合必定相交
if (x1 == x2 && y1 == y2)return true;
//this在r1的右上角
else if (x1 > x2 && y1 > y2)k = 0;
//this在r1的左下角
else if (x1 < x2 && y1 < y2)k = 1;
//this在r1的左上角
else if (x1 < x2 && y1 > y2)k = 2;
//this在r1的右下角
else if (x1 > x2 && y1 < y2)k = 3;
//this和r1横坐标相等
else if (x1 == x2)k = 4;
//纵坐标相等
else if (y1 == y2)k = 5;
//根据不同情况选择不同判断方式
//down1代表this的下边y值,up1代表上边y值,left1代表左边x值,right1代表右边x值
//2同理
//条件成立return true 注意画图了解,自己画图浅显易懂
switch (k) {
case 0:
if (down1 <= up2 && left1 <= right2)return true;
break;
case 1:
if (down2 <= up1 && left2 <= right1) return true;
break;
case 2:
if (down1 <= up2 && left2 <= right1)return true;
break;
case 3:
if (down2 <= up1 && left1 <= right2)return true;
break;
case 4:
if ((y1 - y2 > 0 ? y1 - y2 : y2 - y1) <= h1 / 2 + h2 / 2)return true;
break;
case 5:
if ((x1 - x2 > 0 ? x1 - x2 : x2 - x1) <= w1 / 2 + w2 / 2)return true;
break;
default:
break;
}
return false;
}
private:
CPoint cp;
HW hw;
};
int main() {
CPoint cp1, cp2;
HW hw1, hw2;
cout << "请输入第一个矩形的中心点坐标x,y" << endl;
cin >> cp1.x >> cp1.y;
cout << "请输入第一个矩形的高宽,h,w" << endl;
cin >> hw1.h >> hw1.w;
cout << "请输入第二个矩形的中心点坐标x,y" << endl;
cin >> cp2.x >> cp2.y;
cout << "请输入第二个矩形的高宽,h,w" << endl;
cin >> hw2.h >> hw2.w;
Rect r1, r2;
r1.Init(cp1, hw1);
r2.Init(cp2, hw2);
cout << (r2.judge(r1) ? "相交了!" : "没有相交") << endl;
}