Javascript 快速矩形到矩形交集

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2752349/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:45:40  来源:igfitidea点击:

Fast rectangle to rectangle intersection

javascriptc++language-agnosticgraphics

提问by TheFlash

What's a fast way to test if 2 rectangles are intersecting?

测试两个矩形是否相交的快速方法是什么?



A search on the internet came up with this one-liner (WOOT!), but I don't understand how to write it in Javascript, it seems to be written in an ancient form of C++.

在互联网上搜索了这个单行(WOOT!),但我不明白如何用Javascript编写它,它似乎是用一种古老的C++形式编写的。

struct
{
    LONG    left;
    LONG    top;
    LONG    right;
    LONG    bottom;
} RECT; 

bool IntersectRect(const RECT * r1, const RECT * r2)
{
    return ! ( r2->left > r1->right
        || r2->right < r1->left
        || r2->top > r1->bottom
        || r2->bottom < r1->top
        );
}

回答by Daniel Vassallo

This is how that code can be translated to JavaScript. Note that there is a typo in your code, and in that of the article, as the comments have suggested. Specifically r2->right leftshould be r2->right < r1->leftand r2->bottom topshould be r2->bottom < r1->topfor the function to work.

这就是将代码转换为 JavaScript 的方式。请注意,正如评论所建议的那样,您的代码和文章中的代码有错别字。具体r2->right left应该r2->right < r1->left并且r2->bottom top应该是r2->bottom < r1->top为了使该功能正常工作。

function intersectRect(r1, r2) {
  return !(r2.left > r1.right || 
           r2.right < r1.left || 
           r2.top > r1.bottom ||
           r2.bottom < r1.top);
}

Test case:

测试用例:

var rectA = {
  left:   10,
  top:    10,
  right:  30,
  bottom: 30
};

var rectB = {
  left:   20,
  top:    20,
  right:  50,
  bottom: 50
};

var rectC = {
  left:   70,
  top:    70,
  right:  90,
  bottom: 90
};

intersectRect(rectA, rectB);  // returns true
intersectRect(rectA, rectC);  // returns false

回答by DS.

function intersect(a, b) {
  return (a.left <= b.right &&
          b.left <= a.right &&
          a.top <= b.bottom &&
          b.top <= a.bottom)
}

This assumes that the topis normally less than bottom(i.e. that ycoordinates increase downwards).

这假设top通常小于bottom(即y坐标向下增加)。

回答by Schwarrior

This is how the .NET Framework implements Rectangle.Intersect

这就是 .NET Framework 如何实现 Rectangle.Intersect

public bool IntersectsWith(Rectangle rect)
{
  if (rect.X < this.X + this.Width && this.X < rect.X + rect.Width && rect.Y < this.Y + this.Height)
    return this.Y < rect.Y + rect.Height;
  else
    return false;
}

Or the static version:

或静态版本:

public static Rectangle Intersect(Rectangle a, Rectangle b)
{
  int x = Math.Max(a.X, b.X);
  int num1 = Math.Min(a.X + a.Width, b.X + b.Width);
  int y = Math.Max(a.Y, b.Y);
  int num2 = Math.Min(a.Y + a.Height, b.Y + b.Height);
  if (num1 >= x && num2 >= y)
    return new Rectangle(x, y, num1 - x, num2 - y);
  else
    return Rectangle.Empty;
}

回答by Duke

Another more simple way. (This assumes the y-axis increases downwards).

另一种更简单的方法。(这假设 y 轴向下增加)。

function intersect(a, b) {
  return Math.max(a.left, b.left) < Math.min(a.right, b.right) &&
          Math.max(a.top, b.top) < Math.min(a.bottom, b.bottom);
}

The 4 numbers (max's and min's) in the condition above also give the intersection points.

上面条件中的 4 个数字(最大值和最小值)也给出了交点。

回答by englebart

This has a Rect type you can use. It is already JavaScript.

这有一个你可以使用的 Rect 类型。它已经是 JavaScript。

https://dxr.mozilla.org/mozilla-beta/source/toolkit/modules/Geometry.jsm

https://dxr.mozilla.org/mozilla-beta/source/toolkit/modules/Geometry.jsm

回答by Langerz

I used a blend of methods, to detect a smaller rectangle inside a large rectangle. This is a nodejs method and uses width/height but can easily be adapted.

我使用了多种方法来检测大矩形内的较小矩形。这是一种 nodejs 方法,使用宽度/高度,但可以轻松调整。

            isIntersectingRect: function (r1, r2) {
              var quickCheck = (r1.x <= r2.x + r2.w &&
                      r2.x <= r1.x + r1.w &&
                      r1.y <= r2.y + r2.h &&
                      r2.y <= r1.y + r1.h)
              if (quickCheck) return true;
              var x_overlap = Math.max(0, Math.min(r1.x + r1.w, r2.x + r2.w) - Math.max(r1.x, r2.x));
              var y_overlap = Math.max(0, Math.min(r1.y + r1.h, r2.y + r2.h) - Math.max(r1.y, r2.y));
              var overlapArea = x_overlap * y_overlap;
              return overlapArea == 0;
            }