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

发布于 2024-10-19 08:54:13 字数 641 浏览 7 评论 0原文

我正在寻找一种简单的方法来计算两个矩形之间的差异。我的意思是属于其中一个矩形的所有点,但不属于两个矩形(所以它就像异或)。

在这种情况下,矩形是轴对齐的,因此只有直角。我相信差异区域可以用 0-4 个矩形表示(如果两个矩形相同则为 0,如果只有一个边缘不同则为 1,一般情况下为 4),并且我想将差异区域作为列表获取的矩形。

您还可以将其视为移动/调整实心矩形大小时必须更新的屏幕区域。

示例:将矩形“a”的宽度加倍 - 我想要添加的区域 (R)。

+----+----+
| a  | R  |
|    |    |
+----+----+                   

相交矩形(a 和 b) - 我想要矩形中 T、L、R 和 B 给出的区域(可能有其他分区),但不包括 X:

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

我更喜欢 python 解决方案/库,但任何强大的算法都会有所帮助。

I'm looking for a simple way to calculate the difference between two rectangles. I mean all points which belong to one of the rectangles, but not to both (so it's like XOR).

The rectangles are axis-aligned in this case, so there will be only right angles. I believe the difference region can be expressed in 0-4 rectangles (0 if both rectangles are the same, 1 if just one edge is different, 4 in the general case), and I'd like to get the difference region as a list of rectangles.

You can also think of it as the areas of the screen that have to be updated when a solid rectangle is moved/resized.

Examples: Doubling the width of rectangle "a" - I want the added region (R).

+----+----+
| a  | R  |
|    |    |
+----+----+                   

Intersecting rectangles (a and b) - I want the area given by T, L, R and B in rectangles (other partitioning possible), but excluding X:

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

I'd prefer a python solution/library, but any robust algorithm would be helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤蝉 2024-10-26 08:54:13

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

Split the problem down onto a per-axis basis. Your rectangles can be defined in terms of their spans on each axis - find the interesting points on each axis where a rectangle starts or ends and then define your results in those terms. This'll give you 6 rectangles of difference areas, you can easily combine them down to the four you've illustrated or eliminate degenerate zero-area rectangles if you need to.

Here's a Java implementation:

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;
    }
}
醉态萌生 2024-10-26 08:54:13

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

称为“4区矩形差”。

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

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

There is an algorithm in this link:
https://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Rectangle_difference

It is called "4-zone Rectangle Difference".

It basically computes the four possible rectangles that may remain after subtracting one rectangle from other.

In this case, the algorithm have to be run twice.

惜醉颜 2024-10-26 08:54:13

我想象找到相交矩形(即 X)的面积,并从矩形 a + 矩形 b 的组合面积中扣除该面积,即可得出您的解决方案。

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

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

I would imagine finding the area of the intersecting rectangle (that is X) and deducting that from the combined area of rectangle a + rectangle b will give your solution.

I found this on my hunt for a quick answer:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文