两个矩形之间的差异(XOR),作为矩形呈现?

8
我正在寻找一种简单的方法来计算两个矩形之间的差异。具体指的是所有属于其中一个矩形但不属于另一个矩形的点(因此就像XOR)。在这种情况下,矩形是轴对齐的,因此只会有直角。我相信差异区域可以表示为0-4个矩形(如果两个矩形相同,则为0;如果只有一个边缘不同,则为1;在一般情况下为4),我希望将差异区域作为矩形列表获取。您也可以将其视为在移动/调整实心矩形时必须更新的屏幕区域。例如:将矩形“a”的宽度加倍 - 我想要添加的区域(R)。
+----+----+
| a  | R  |
|    |    |
+----+----+                   

相交的矩形(a和b)- 我想要在矩形(其他分区也可能)中给定由T、L、R和B确定的区域的面积,但不包括X:


+------------+  a
|      T     |
|·····+------+-----+  b
|  L  | X    |  R  |
|     |      |     |
+-----+------+·····|
      |    B       |
      +------------+

我更倾向于使用Python的解决方案/库,但任何稳健的算法都会有所帮助。

3个回答

11

将问题分解为每个坐标轴的基础上。可以根据矩形在每个坐标轴上的跨度来定义它们 - 找到每个坐标轴上感兴趣的点,其中矩形开始或结束,然后用这些术语定义结果。这将给您带来6个面积不同的矩形,您可以轻松地将它们合并为您所说明的四个矩形,或者如果需要,消除退化的零面积矩形。

下面是Java实现:

public class Rect
{
    private float minX, maxX, minY, maxY;

    public Rect( float minX, float maxX, float minY, float maxY )
    {
        this.minX = minX;
        this.maxX = maxX;
        this.minY = minY;
        this.maxY = maxY;
    }

    /**
     * Finds the difference between two intersecting rectangles
     * 
     * @param r
     * @param s
     * @return An array of rectangle areas that are covered by either r or s, but
     *         not both
     */
    public static Rect[] diff( Rect r, Rect s )
    {
        float a = Math.min( r.minX, s.minX );
        float b = Math.max( r.minX, s.minX );
        float c = Math.min( r.maxX, s.maxX );
        float d = Math.max( r.maxX, s.maxX );

        float e = Math.min( r.minY, s.minY );
        float f = Math.max( r.minY, s.minY );
        float g = Math.min( r.maxY, s.maxY );
        float h = Math.max( r.maxY, s.maxY );

        // X = intersection, 0-7 = possible difference areas
        // h ┌─┬─┬─┐
        // . │5│6│7│
        // g ├─┼─┼─┤
        // . │3│X│4│
        // f ├─┼─┼─┤
        // . │0│1│2│
        // e └─┴─┴─┘
        // . a b c d

        Rect[] result = new Rect[ 6 ];

        // we'll always have rectangles 1, 3, 4 and 6
        result[ 0 ] = new Rect( b, c, e, f );
        result[ 1 ] = new Rect( a, b, f, g );
        result[ 2 ] = new Rect( c, d, f, g );
        result[ 3 ] = new Rect( b, c, g, h );

        // decide which corners
        if( r.minX == a && r.minY == e || s.minX == a && s.minY == e )
        { // corners 0 and 7
            result[ 4 ] = new Rect( a, b, e, f );
            result[ 5 ] = new Rect( c, d, g, h );
        }
        else
        { // corners 2 and 5
            result[ 4 ] = new Rect( c, d, e, f );
            result[ 5 ] = new Rect( a, b, g, h );
        }

        return result;
    }
}

3

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接