Прямоугольное пересечение.распечатать сообщение для пустого пересечения - PullRequest
0 голосов
/ 28 мая 2018

У меня четыре координаты: x, y, ширина = w, высота = 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 голосов
/ 28 мая 2018

Предполагая, что у вас есть кое-что не очень отличающееся от:

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

(или то же самое, используя float или double вместо int)

Я предполагаю, что здесьw и h всегда положительны, если они могут быть отрицательными, вы должны сначала нормализовать входной прямоугольник, чтобы убедиться, что они есть.

Вы найдете пересечение, найдя его противоположные углы и убедившись, что нижеслева до верхнего правого:

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;
    }
}
0 голосов
/ 28 мая 2018

Метод, который вы используете для пересечения прямоугольников НЕ работает , когда прямоугольники представлены с их шириной и высотой.

Он может работать, если вы храните два противоположных угла прямоугольников (вместо этогоодного угла и размеров) и убедитесь, что координаты первого угла всегда меньше или равны второму углу, эффективно сохраняя min_x, min_y, max_x и max_y для ваших прямоугольников.

Я бы предложил принять соглашение о том, чтобы прямоугольники всегда включали их min координаты и всегда исключали их max координаты.

...