矩形相交问题

矩形相交问题

数据结构

// 定义一个点类型
struct point{
    double x;
    double y;
};

// 定义一个矩形类型
struct rect {
    struct point pt1;   // 矩形的左上角顶点
    struct point pt2;   // 矩形的右下角定点
}

规定坐标轴采用下图所示坐标轴
image

判断一个点在一个矩形中

// 规定矩形包含上边和左边,不包含下边和右边
int ptInRect(struct point pt, struct rect rt){
	return (pt.x >= rt.pt1.x && pt.x < rt.pt2.x
		& pt.y >= rt.pt1.y && pt.y < rt.pt2.y);
}

判断两个矩形是否相交

方法一

通过矩形的重心来判断

由数学知识,如果两个矩形相交,则这两个矩形的重心的连线在x轴的投影会小于这个两个矩形的宽的和的一半,并且在y轴的投影会小于这两个矩形的高的和的一半。

// 检测两个矩形是否相交
// 方法根据重心判断
int checkCross(struct rect rt1, struct rect rt2){
	struct point pt1;		// rt1的重心
	struct point pt2;		// rt2的重心

	double width1;			// rt1的宽
	double height1;			// rt1的高
	double width2;			// rt2的宽
	double height2;			// rt2的高

        // 获得矩形的重心
	pt1.x = (rt1.pt1.x + rt1.pt2.x);
	pt1.y = (rt1.pt1.y + rt1.pt2.y);
	pt2.x = (rt2.pt1.x + rt2.pt2.x);
	pt2.y = (rt2.pt1.y + rt2.pt2.y);

        // 获得矩形的宽度和高度
	width1 = rt1.pt2.x - rt1.pt1.x;
	height1 = rt1.pt2.y - rt1.pt1.y;
	width2 = rt2.pt2.x - rt2.pt1.x;
	height2 = rt2.pt2.y - rt2.pt1.y;

        // 判断并返回
	return (fabs(pt2.x - pt1.x) < (width1 / 2 + width2 / 2)
		&& fabs(pt2.y - pt1.y) < (height1 /2 + height2 / 2));
}

这种方法只能用来检测,但是如果想要获得两个矩形的重叠矩形的坐标就很难。

方法二

假设法,通过假设矩形重叠来逆推结果,如果矩形真的相交可以很方便获得重叠矩形的坐标。

假设两个矩形重叠,则可以通过这两个矩形的坐标计算出重叠矩形的坐标。如果这个矩形rt(p1, p2)存在,则必须有:

p1.x < p2.x && p1.y < p2.y
#define min(x, y) (((x) < (y)) ? (x) : (y))
#define max(x, y) (((x) > (y)) ? (x) : (y))

// 检测两个矩形是否相交
// 假设法
int checkCross(struct rect rt1, struct rect rt2){
	struct rect overlap;

        // 获得重叠矩阵的坐标
	overlap.pt1.x = max(rt1.pt1.x, rt2.pt1.x);
	overlap.pt1.y = max(rt1.pt1.y, rt2.pt1.y);
	overlap.pt2.x = min(rt1.pt2.x, rt2.pt2.x);
	overlap.pt2.y = min(rt1.pt2.y, rt2.pt2.y);

        // 判断是否重叠,并返回
	return (overlap.pt1.x < overlap.pt2.x 
		&& overlap.pt1.y < overlap.pt2.y);
}

拓展

  • 求两个矩形相交的面积
  • 求三个矩形相交的面积
  • ...
posted @ 2017-02-17 11:47  soiios  阅读(449)  评论(0编辑  收藏  举报