Вычтите CGRect из CGRect - самый большой кусок, не содержащий другого

Как я могу вычесть один CGRect из другого? Я хочу, чтобы результат R1 - R2 был самым большим подправалом R1, который не пересекается с R2.

Пример 1:

+----------------------------------+
| +--------+                       |
| |   R2   |                       |
| |        |                       |
| +--------+      R1               |
|                                  |
|                                  |
|                                  |
+----------------------------------+

R3 = CGRectSubstract (R2, R1);

            +----------------------+
            |                      |
            |                      |
            |                      |
            |          R3          |
            |                      |
            |                      |
            |                      |
            +----------------------+

Пример 2:

+-----------------------+----------+
|                       |          |
|                       |    R2    |
|                       |          |
|                 R1    +----------+
|                                  |
|                                  |
|                                  |
+----------------------------------+

R3 = CGRectSubstract (R2, R1);

+-----------------------+
|                       |
|                       |
|                       |
|          R3           |
|                       |
|                       |
|                       |
+-----------------------+

Пример 3:

+----------------------------------+
|                                  |
|                                  |
|                                  |
|                 R1               |
|         +---------+              |
|         |         |              |
|         |   R2    |              |
+---------+---------+--------------+

R3 = CGRectSubstract (R2, R1);

+----------------------------------+
|                                  |
|                                  |
|              R3                  |
|                                  |
+----------------------------------+



Ответы

Ответ 1

Ваше определение довольно неоднозначно, что говорит о том, является ли вычитание горизонтальным или вертикальным? Я рекомендую использовать комбинацию CGRectIntersection и CGRectDivide, а также указать направление удаления двусмысленности.

(не протестирован или даже скомпилирован)

CGRect rectSubtract(CGRect r1, CGRect r2, CGRectEdge edge) {
    // Find how much r1 overlaps r2
    CGRect intersection = CGRectIntersection(r1, r2);

    // If they don't intersect, just return r1. No subtraction to be done
    if (CGRectIsNull(intersection)) {
        return r1;
    }

    // Figure out how much we chop off r1
    float chopAmount = (edge == CGRectMinXEdge || edge == CGRectMaxXEdge)
                       ? intersection.size.width
                       : intersection.size.height;

    CGRect r3, throwaway;
    // Chop
    CGRectDivide(r1, &throwaway, &r3, chopAmount, edge);
    return r3;
}

Ответ 2

CGRect newRect = CGRectMake(0, 0, rect2.size.width - rect1.size.width, rect2.size.height - rect1.size.height);

В ответ на вашу иллюстрацию этот код, который я вам привел, будет делать именно то, что вы хотите (при условии, что вам не нужны координаты координат XY). Я просмотрел docs для функций CGGeometry, и, похоже, не существует CGRectDifference или другого такого метода. Однако есть CGRectUnion, но это делает противоположное тому, что вы ищете.

Ответ 3

Возможно, что-то вроде этого:

CGRect frame = CGRectMake(0, 0, 320, 480);
float aWidth  = frame.size.width; /* say for instance 320 */
float aHeight = frame.size.height; /* say for instance 480 */

int final = aWidth - aHeight;
NSLog(@"Should be -160, your answer: %i",final);