题目描述
用CPoint表示点,用两个CPoint对象表示矩形类CRect的对角线两点。分别实现CPoint类和CRect类,并在主函数用输入的坐标定义4个CPoint类对象,每2个CPoint对象再构造1个CRect对象,然后写个友元函数,判断2个矩形是否重叠。
输入
判断次数
矩形1的对角线顶点坐标x1, y1, x2, y2
矩形2的对角线顶点坐标x1, y1, x2, y2
......
输出
是否重叠
样例查看模式
正常显示查看格式
输入样例1
3
1 5 2 9
1 3 2 4
5 6 7 8
5 7 7 7
2 5 1 0
9 4 2 9
输出样例1
not overlapped
overlapped
overlapped
/******************************************************************************************/
这道题的难点在于,如何判断矩阵是否重叠,已知两个矩阵的两个分别的顶点,但是无法判断哪个顶点的位置关系以及两个矩阵的位置关系。
因此需要一个可以忽略以上不确定性的算法来实现判断。
设计思路:
(1)已知一个矩阵的两个顶点,则可直接得到矩阵的中心点P(Fx1 , Fy1)、Q(Fx2 , Fy2);
(2) 由两个中心点可以计算二者间的x间距和y间距,记为Dx , Dy ;
(3)利用fabs函数(取绝对值)来分别获取在x轴方向和y轴方向点P到矩阵1的距离Dx1和Dy1,点Q到矩阵2的距离Dx2和Dy2 ,如图所示;
(4)则可根据Dx与Dx1+Dx2 与Dy和Dy1 + Dy2 的量值关系判断两个矩阵是否重叠;
当Dx <= Dx1 + Dx2 与 Dy <= Dy1 + Dy2 同时成立时,两个矩阵重叠,否则不重叠;
故以上述算法为基础的代码如下:
#include <iostream>
#include <math.h>
using namespace std;
class CPoint //单个点的类
{
public:
int x ;
int y ;
public:
CPoint(int x0 , int y0)
{
x = x0 ;
y = y0 ;
}
};
class CRect //单个矩阵的类
{
CPoint p1 ;
CPoint p2 ;
public:
CRect(int x1 , int y1 , int x2 , int y2):p1(x1 , y1) , p2(x2 , y2)
{
}
friend bool overlap(CRect &cr1 , CRect &cr2) ; //友元函数判断矩阵是否重叠 ;
};
bool overlap(CRect &cr1 , CRect &cr2) //算法的实现
{
float Fx1 , Fy1 ;
float Fx2 , Fy2 ;
Fx1 = (cr1.p1.x + cr1.p2.x )/2.0 ; //这里注意 除的是2.0保证Fx、Fy为浮点数;
Fy1 = (cr1.p1.y + cr1.p2.y )/2.0 ;
Fx2 = (cr2.p1.x + cr2.p2.x )/2.0 ;
Fy2 = (cr2.p1.y + cr2.p2.y )/2.0 ;
float Dx1 = fabs(Fx1 - cr1.p1.x) ; //abs函数返回int ; fabs函数返回float ;
float Dy1 = fabs(Fy1 - cr1.p1.y) ;
float Dx2 = fabs(Fx2 - cr2.p1.x) ;
float Dy2 = fabs(Fy2 - cr2.p1.y) ;
float Dx = fabs(Fx1 - Fx2) ;
float Dy = fabs(Fy1 - Fy2) ;
if(Dx <= Dx1 + Dx2 && Dy <= Dy1 + Dy2)
return true ;
return false ;
}
int main()
{
int t ;
cin >> t ;
while(t--)
{
int x1 , y1 , x2 , y2 ;
cin >> x1 >> y1 >> x2 >> y2 ;
CRect a1(x1, y1 , x2 , y2 ) ;
cin >> x1 >> y1 >> x2 >> y2 ;
CRect a2(x1, y1 , x2 , y2 ) ; //两个矩阵的获取 输入 ;
if(overlap(a1 , a2))
{
cout << "overlapped" << endl ;
}
else
{
cout << "not overlapped" << endl ; //输出结果 ;
}
}
}