【问题标题】:Check amount of 'overlap' of two sides of adjacent rectangles检查相邻矩形两侧的“重叠”量
【发布时间】:2020-11-19 22:21:23
【问题描述】:

我有两个保证不重叠的矩形。

但是,我需要知道它们是否彼此相邻,以及它们是否以两个或更多单位相互接触。例如,以下矩形相距 4 个单位。

在上面的例子中,我比较了以下内容:

rect1 = {
   x: 4,
   y: 4,
   width: 3,
   height: 5
}

和

rect2 = {
   x: 7,
   y: 1,
   width: 4,
   height: 7
}

我目前正在尝试通过几个嵌套的 if/else 语句来实现这一点,但我知道会有更合适的方法。

什么是完成此任务的有效方法?

免责声明:

我在标题中使用了 overlap 这个词,因为我不确定如何描述它,即使它们实际上并不重叠。

【问题讨论】:

  • 你可以做这样的检查 a.x > (b.x + b.w) || (a.x + a.w) (b.y +b.h) ||(a.y + a.h)
  • 您要使用的术语是“相邻”:您想知道两个矩形是否相邻,如果相邻,则相邻是否覆盖两个或多个单元。话虽如此,如果您已经有工作代码,并且想知道如何改进它,那么 SO 不是问的地方。相反,你想要codereview.stackexchange.com
  • 坦率地说,我认为一堆 IF 语句将是最有效的方法。你只比较几个数字,一些加法,就是这样。没有内存分配,没有函数调用,什么都没有。我会选择 IF。
  • @StefanAvramovic 您的代码到底在做什么?它看起来更像是检查重叠对象的代码。
  • @Mike'Pomax'Kamermans - 还没有完全工作。我正在研究它,并对所有嵌套感到困惑,我意识到我应该检查一下是否有更简单的解决方案。

标签: javascript overlap


【解决方案1】:

这是一个简单的版本:

function rectOverlaps2(r1, r2) {
    let overlapX, overlapY;

    if ( r1.x <= r2.x ) {
        overlapX = r1.x + r1.width - r2.x;
    } else {
        overlapX = r2.x + r2.width - r1.x;
    }

    if ( r1.y <= r2.y ) {
        overlapY = r1.y + r1.height - r2.y;
    } else {
        overlapY = r2.y + r2.height - r1.y;
    }

    return (overlapX == 0 && overlapY >= 2) || (overlapY == 0 && overlapX >= 2);
}

补充:刚刚意识到有一个边缘情况 - 如果一个矩形的重叠尺寸(宽度或高度)仅为 1 个单位,则不应计算重叠。由于这看起来像是一个家庭作业问题,因此将其作为练习留给读者。

【讨论】:

  • 不,不是作业问题。仍然需要处理您的代码,但我认为overlapY &gt;= 2 考虑到了边缘情况。
  • @kojow7 - 不,这只是两个矩形边缘之间的距离。想象一个非常大的 (100x100) 矩形与中间的一个小 (1x1) 矩形接触。 OverlapY 类似于 50,但触摸区域仍然只有 1 个正方形。
【解决方案2】:

这是我对这个问题的解决方案。例如,我的想法是创建一个数组,其中包含矩形起点和 Y 方向终点之间的所有数字。然后,如果另一个矩形包含介于两者之间的任何索引,则意味着它们“重叠”

我没有尝试任何性能优化,但这是一般的想法。

rect1 = {
   x: 4,
   y: 4,
   width: 3,
   height: 5
}

rect2 = {
   x: 7,
   y: 1,
   width: 4,
   height: 7
}


function createMap(start, end) {
  return Array(end - start + 1).fill().map((_, idx) => start + idx)
}

function getEndPoints(rect){
  const endX = rect.x + rect.width;
  const endY = rect.y + rect.height;
  return {endX, endY}; 
}

function getOverlap(r1, r2){
  const r1Range = createMap(r1.y, r1.endY);
  const r2Range = createMap(r2.y, r2.endY);
  const verticalOverlap = r1Range.filter(val => !r2Range.includes(val));
  console.log(`These two rectangles overlap by: ${verticalOverlap.length} squares`)
  // Then just do the same for horizontal
}

rect1 = {...rect1, getEndpoints(rect1)}
rect2 = {...rect2, getEndpoints(rect2)}

getOverlap(rect1, rect2);

【讨论】:

    猜你喜欢
    • 2017-05-13
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 2018-09-29
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多