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

Posted

技术标签:

【中文标题】两个矩形之间的差异(XOR),作为矩形?【英文标题】:Difference (XOR) between two rectangles, as rectangles? 【发布时间】:2011-07-05 21:39:04 【问题描述】:

我正在寻找一种简单的方法来计算两个矩形之间的差异。我的意思是属于其中一个矩形的所有点,但不属于两者(所以它就像 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 解决方案/库,但任何强大的算法都会有所帮助。

【问题讨论】:

【参考方案1】:

将问题分解到每个轴的基础上。您的矩形可以根据它们在每个轴上的跨度来定义 - 在每个轴上找到矩形开始或结束的有趣点,然后用这些术语定义您的结果。这将为您提供 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;
    

【讨论】:

【参考方案2】:

我想找到相交矩形(即 X)的面积,然后从矩形 a + 矩形 b 的组合面积中减去该面积,即可得到您的解决方案。

我在寻找快速答案时发现了这个:

http://tekpool.wordpress.com/2006/10/12/rectangle-intersection-find-the-intersecting-rectangle/

【讨论】:

【参考方案3】:

此链接中有一个算法: https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Rectangle_difference

称为“四区矩形差”。

它基本上计算了从另一个矩形中减去一个矩形后可能剩下的四个可能的矩形。

在这种情况下,算法必须运行两次。

【讨论】:

以上是关于两个矩形之间的差异(XOR),作为矩形?的主要内容,如果未能解决你的问题,请参考以下文章

如何注释条之间的差异?

查找行之间的绝对差异并将差异与其他行进行比较

虽然找到2张图片之间的差异,但OpenCV差异大于预期

创建一个差异矩阵比较R数据框中所有行之间的差异

如何在 VBA 中查找日期之间的差异

映射器执行时间之间的巨大差异