- // 定义一个点类型
- struct point{
- double x;
- double y;
- };
- // 定义一个矩形类型
- struct rect {
- struct point pt1; // 矩形的左上角顶点
- struct point pt2; // 矩形的右下角定点
- }
规定坐标轴采用下图所示坐标轴
- // 规定矩形包含上边和左边,不包含下边和右边
- 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);
- }
来源: http://www.bubuko.com/infodetail-1947827.html