OOP 判断矩形是否重叠(复合类+友元)

题目描述

用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 ;              //输出结果 ; 
        }
            
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值