C/C++实现,如何判断两个矩形是否相交?

一.需求分析

我们需要定义一个矩形类,属性有中心点坐标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;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值