長方形から長方形への高速交差


81

2つの長方形が交差しているかどうかをテストする簡単な方法は何ですか?


インターネットで検索してこのワンライナー(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
        );
}

5
コピー/貼り付けにタイプミスがあったと思います
fmark 2010年

5
元の記事にはタイプミスがあります。r2->right left意味がありません。HTMLエスケープの問題が原因で壊れている可能性があります。
マルセロカントス2010年

42
上記のコードがC ++の「最新の」形式でどのように異なると思うか興味があります。
jamesdlin 2010年

3
欠落している文字は<、HTMLのエスケープによる記号であると確信しています。
devios1 2011年

1
@jamesdlinは、1つのパラメーターを取り、構造体のメンバー関数として関数を作成します。次に、通常はconst *の代わりにconst&を使用します。Win32マクロを使用する代わりに、テンプレートを使用してint、long、doubleの両方のバージョンを使用できます...(RECTはタイプ名ではなく、名前のない構造体のインスタンスになるため、どちらもコンパイルされません。)例:ideone.com/bnzwl3
Sebastian Wahl

回答:


142

これは、そのコードを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);
}

テストケース:

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

追加/確認するだけです-これは、20px x 20pxの3つのボックスをテストしています。ただし、rectBは30px x 30pxです
verenion

6
r1とr2が同一の場合、intersectRect関数はfalseを返します
zumalifeguard 2013

素晴らしい雄弁な実装。大好きです!+1、私のゲームでは完璧に機能しました。
unome 2014

1
@zumalifeguardどうしてそう思うの?
minix 2015

この機能はとても天才です。私はそれを考えたことはなかったでしょう、代わりに私は2つのボックスを交差させようとしたでしょう。
nikk wong 2018

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

これは、topが通常より小さいbottom(つまり、y座標が下向きに増加する)ことを前提としています。


優れた実用的なソリューションですが、すべての条件を評価する必要があるため、少し遅くする必要があります。もう1つの解決策は、条件の1つがtrueと評価されるとすぐに実行されます。
ギゴ2013年

21
これは、条件の1つがfalseと評価されるとすぐに実行されます。つまり、他の場合とまったく同じ場合です。
DS。

3
これは否定アクションを削除するのでより良いです。
Discipol 2013年

4
+1、受け入れられた答えよりもずっときれい。ハーフオープン範囲を使用している場合(つまり、多くのグラフィックシステムで一般的なように、長方形には上と左が含まれますが、下と右は含まれません)、に変更<=する<と機能するはずです。
ジュール

=条件ごとにを削除でき、長方形が境界線に「接触」できるため、このソリューションが気に入っています。
プログラムハンマー2017年

20

これは、.NETFrameworkが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;
}

または静的バージョン:

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;
}

6

もう1つのもっと簡単な方法。(これは、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);
}

上記の条件の4つの数値(最大値と最小値)も交点を示します。



0

大きな長方形の中の小さな長方形を検出するために、さまざまな方法を使用しました。これは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;
            }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.