如何检测某个范围(部分)是否位于其他范围内?

Tom*_*Tom 2 algorithm math tree comparison

让我们说我有两个正方形,我知道他们的位置,红色和蓝色方块:

redTopX;
redTopY;
redBotX;
redBotY;
blueTopX;
blueTopY;
blueBotX;
blueBotY;
Run Code Online (Sandbox Code Playgroud)

现在,我想检查方形蓝色是否位于(或部分)方形红色内(部分).这可能发生在很多情况下,正如您在我创建的图像中看到的那样,可以更好地说明我的情况: 替代文字http://www.feedpostal.com/etc/ranges.gif

请注意,总是只有一个蓝色和一个红色方块,我只是添加了多个,所以我不需要重绘18次.

我原来的逻辑很简单,我检查方形蓝色的所有角落,看看它们是否在方形红色内:

if (
((redTopX >= blueTopX) && (redTopY >= blueTopY) && (redTopX <= blueBotX) && (redTopY <= blueBotY)) || //top left
((redBotX >= blueTopX) && (redTopY >= blueTopY) && (redBotX <= blueBotX) && (redTopY <= blueBotY)) || //top right
((redTopX >= blueTopX) && (redBotY >= blueTopY) && (redTopX <= blueBotX) && (redBotY <= blueBotY)) || //bottom left
((redBotX >= blueTopX) && (redBotY >= blueTopY) && (redBotX <= blueBotX) && (redBotY <= blueBotY)) //bottom right
) {
    //blue resides in red
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这种逻辑存在一些缺陷.例如,如果红色环绕蓝色(如情况1)怎么办?

我认为这很容易,但我很难想出一个很好的方法来覆盖所有这些情况..任何人都可以帮助我吗?

问候,汤姆

AnT*_*AnT 6

检查红色矩形是否完全位于蓝色矩形之外的测试如下所示

bool outside = 
  redBotX > blueTopX || redTopX < blueBotX || 
  redBotY > blueTopY || redTopY < blueBotY;
Run Code Online (Sandbox Code Playgroud)

现在,负面的将告诉你红色矩形是否与蓝色矩形相交

bool intersects =
  !(redBotX > blueTopX || redTopX < blueBotX || 
    redBotY > blueTopY || redTopY < blueBotY);
Run Code Online (Sandbox Code Playgroud)

如果您愿意,可以应用De Morgan规则并将其重写为

bool intersects =
  redBotX <= blueTopX && redTopX >= blueBotX && 
  redBotY <= blueTopY && redTopY >= blueBotY;
Run Code Online (Sandbox Code Playgroud)

当然,上述测试假设坐标是"标准化的*,即

assert(redBotX <= redTopX && redBotY <= redTopY);
assert(blueBotX <= blueTopX && blueBotY <= blueTopY);
Run Code Online (Sandbox Code Playgroud)

此外,比较可能是严格的或非严格的,具体取决于您是否考虑将矩形触摸为交叉.

编辑:我看到你对矩形坐标使用不同的约定:Top是较低的坐标,Bot是较高的坐标,即

assert(redTopX <= redBotX && redTopY <= redBotY);
assert(blueTopX <= blueBotX && blueTopY <= blueBotY);
Run Code Online (Sandbox Code Playgroud)

要处理这种情况,您只需要在所有条件下交换BotTop坐标.例如,最后一个现在看起来如下

bool intersects =
  redTopX <= blueBotX && redBotX >= blueTopX && 
  redTopY <= blueBotY && redBotY >= blueTopY;
Run Code Online (Sandbox Code Playgroud)