別のサイトからの件を見てください。
問題(アルゴリズム)を反対側から見ると、ケースは非常に単純であることがわかります。
つまり、「長方形は重なっていますか?」という質問に答える代わりに、「長方形は重なっていませんか?」という質問に答えます。
結局、両方の質問は同じ問題を解決しますが、2 番目の質問への答えは実装が簡単です。これは、一方が他方の下にある場合、または一方が他方の左側にある場合にのみ長方形が重ならないためです (一方の質問で十分です)。もちろん、両方が同時に発生することもあります。ここでは、論理条件「または」をよく理解することが重要です)。これにより、最初の質問で考慮する必要がある多くのケースが減少します。
適切な変数名を使用することで、全体の問題も簡素化されます。
const areRectanglesOverlap = (rect1, rect2) => {
let [left1, top1, right1, bottom1] = [rect1[0], rect1[1], rect1[2], rect1[3]],
[left2, top2, right2, bottom2] = [rect2[0], rect2[1], rect2[2], rect2[3]];
// The first rectangle is under the second or vice versa
if (top1 < bottom2 || top2 < bottom1) {
return false;
}
// The first rectangle is to the left of the second or vice versa
if (right1 < left2 || right2 < left1) {
return false;
}
// Rectangles overlap
return true;
}
四角形の表現が異なる場合でも、変数の変更が定義されているセクションのみを変更することで、上記の関数をそれに適応させるのは簡単です。関数の残りの部分は変更されていません (もちろん、ここではコメントは必要ありませんが、この単純なアルゴリズムを誰もがすぐに理解できるようにコメントを追加しました)。
上記の関数と同等ですが、おそらく少し読みにくい形式は次のようになります。
const areRectanglesOverlap = (rect1, rect2) => {
let [left1, top1, right1, bottom1] = [...rect1],
[left2, top2, right2, bottom2] = [...rect2];
return !(top1 < bottom2 || top2 < bottom1 || right1 < left2 || right2 < left1);
}