矩形交点。打印空交集的消息

时间:2018-05-28 06:38:39

标签: c++ mathematical-optimization procedure rectangles

我有四个坐标:x,y,width = w,height = h,我有两个带有以下坐标的矩形:

r1.x=2,r1.y=3,r1.w=5,r1.h=6; 
r2.x=0, r2.y=7,r2.w=-4,r4.h=2

如何观察此交叉点是空的。

到目前为止我做了什么:

rectangle intersection (rectangle r1, rectangle r2){
r1.x=max(r1.x,r2.x);
r1.y=max(r1.y,r2.y);
r1.w=min(r1.w,r2.w);
r1.h=min(r1.h,r2.h);
return r1;
}

我认为以上代码是在有交叉点时使用的,但是当交叉点为空时我不知道。另外,当没有交叉点时,我想打印一条消息“空”。

谢谢!

2 个答案:

答案 0 :(得分:0)

当矩形用宽度和高度表示时,用于矩形交叉的方法不起作用

如果存储矩形的两个相对角(而不是一个角和尺寸)并确保第一个角的坐标始终小于或等于第二个角,它可以工作,有效地存储min_x

,。min_ymax_xmax_y

我建议你采用这样的惯例,即确保矩形始终包含他们的min坐标,并始终排除他们的max坐标。

答案 1 :(得分:0)

假设你有一些与以下内容截然不同的东西:

struct rectangle {
    int x;
    int y;
    int w;
    int h;
};

(或使用floatdouble代替int

我将在此假设wh始终为正数,如果它们可能为负数,则应首先对输入矩形进行标准化以确保它们为。

您可以通过找到相对的角来找到交叉点,并确保左上角位于右上角之前:

rectangle intersection(const rectangle& r1, const rectangle& r2) {
    // optionaly control arguments:
    if (r1.w < 0 || r1.h < 0 || r2.w < 0 || r2.h < 0) {
        throw std::domain_error("Unnormalized rectangles on input");
    }
    int lowx = max(r1.x, r2.x);    // Ok, x coordinate of lower left corner
    int lowy = max(r1.y, r2.y);    // same for y coordinate

    int upx = min(r1.x + r1.w, r2.x + r2.w)  // x for upper right corner
    int upy = min(r1.y + r1.h, r2.y + r2.h)  // y for upper right corner

    if (upx < lowx || upy < lowy) {      // empty intersection
        throw std::domain_error("Empty intersection");
    }
    return rectangle(lowx, lowy, upx - lowx, upy - lowy);
}

您可以通过强制宽度和高度的正值来标准化矩形:

rectangle& normalize(rectangle& r) {
    if (r.w < 0) {
        r.x += r.w;
        r.w = - r.w;
    }
    if (r.h < 0) {
        r.y += r.h;
        r.h = -r.h;
    }
    return r;
}

然后,您可以在第二个函数中使用它来显示交叉结果:

void display_intersection(std::outstream out, rectangle r1, rectangle r2) {
    try {
        rectangle inter = intersection(normalize(r1), normalize(r2));
        out << "(" << inter.x << ", " << inter.y << ") to (";          
        out << inter.x + inter.w << ", " << inter.y + inter.h << ")" << std::endl;
    }
    except (std::domain_error& e) {
        out << "empty" << std::endl;
    }
}