什么是从另一个边界框中减去边界框的最好或有效方法(即,从边界框布尔减法创建n个边界框)?边界框布尔减法?
理想情况下,由此产生的包围盒尽可能地平方,以便有限的“碎片”(即,1宽度,1高度,100深度)。
什么是从另一个边界框中减去边界框的最好或有效方法(即,从边界框布尔减法创建n个边界框)?边界框布尔减法?
理想情况下,由此产生的包围盒尽可能地平方,以便有限的“碎片”(即,1宽度,1高度,100深度)。
这个问题已经很老了,但自从我做到了,我会回答它。
首先想到两个范围(包围盒)作为同心正方形。我们从外部减去内部的一个。
A----------------------------------B
| |
| A----------------------B |
| | | |
| | | |
| D----------------------C |
| |
D----------------------------------C
然后,你将最终得到8个盒子。
A----------------------------------B
| 1 | 2 | 3 |
|----------------------------------|
| | | 4 |
| 8 | | |
|----------------------------------|
| 7 | 6 | 5 |
D----------------------------------C
所以,诀窍是做广场。大多数图形库都有代码来处理'范围'。我将使用Javascript中的OpenLayers作为示例。这个想法是,你通过绘制每对点的对角线并获得边界框,然后使用一些先前制作的边界框的点进行级联,从而制作范围(边界框)。下面的代码应该是自我解释的。我们减去程度E2,其被描绘为内部范围,从某种程度上E1,其被描绘为外部范围:
var b1 = ol.extent.boundingExtent([ol.extent.getTopLeft(e1), ol.extent.getTopLeft(e2)]);
var b2 = ol.extent.boundingExtent([ol.extent.getBottomLeft(b1), ol.extent.getBottomLeft(e2)]);
var b3 = ol.extent.boundingExtent([ol.extent.getBottomLeft(e1), ol.extent.getBottomLeft(e2)]);
var b4 = ol.extent.boundingExtent([ol.extent.getBottomLeft(b3), ol.extent.getBottomRight(e2)]);
var b5 = ol.extent.boundingExtent([ol.extent.getBottomRight(e1), ol.extent.getBottomRight(e2)]);
var b6 = ol.extent.boundingExtent([ol.extent.getBottomRight(b5), ol.extent.getTopRight(e2)]);
var b7 = ol.extent.boundingExtent([ol.extent.getTopRight(e1), ol.extent.getTopRight(e2)]);
var b8 = ol.extent.boundingExtent([ol.extent.getTopLeft(e1), ol.extent.getTopLeft(b7)]);
例如,注意我们如何使用从边框B1使B2的坐标, b3使b4等
现在我们知道,范围可能不是同心。有些框可能超出我们的答案。然而,需要注意的一个很酷的情况是,如果减法范围(e2)的一个角落在基本范围(e1)内,那么我们需要三个连接的盒子。所以,如果e2的左上角在e1中,那么我们需要b1,b2和b8。同样,如果e2的左下角在e1中,那么我们需要b6,b7和b8。您可能会注意到一些重复内容,例如b8,但我们稍后会将其过滤掉。所以,让我们收集我们的结果。
var results = [];
if (ol.extent.containsCoordinate(e1, ol.extent.getTopLeft(e2))) {
results.push(b1, b2, b3);
}
if (ol.extent.containsCoordinate(e1, ol.extent.getTopRight(e2))) {
results.push(b8, b7, b6);
}
if (ol.extent.containsCoordinate(e1, ol.extent.getBottomRight(e2))) {
results.push(b6, b5, b4);
}
if (ol.extent.containsCoordinate(e1, ol.extent.getBottomLeft(e2))) {
results.push(b2, b3, b4);
}
消除重复,还要注意这样的事实,尤其是在范围共享边界的情况下,其中的一些盒子将是“空”。通常情况下,您可以通过与范围相关的getArea()函数来计算出结果。下面是一个聪明的JavaScript方法来过滤掉数组中的重复对象,因为Array.indexOf使用'==='并且只返回它的第一个匹配。而且,我们只收集实际上有区域的盒子。
results = results.filter(function(a,i,arr) {
return arr.indexOf(a) === i && ol.extent.getArea(a) > 0;
});
注意事项使用:
要注意,如果两个初始边界框不相交,将导致一个空的列表。所以,这种方法只适用于相交的范围。图形库通常具有用于两个区域相交的布尔函数。例如,如果您正在寻找加载潜在范围(e1)减去已加载(e2)并且它们不相交的潜在范围(e1),那么您可能只想直接加载e1。取决于你的申请。
希望这答案对某人有用!
是否有您喜欢的解决方案的特定语言,或者您刚刚使用算法? – 2010-10-25 00:17:49
我使用c#,但如果有人用另一种语言,我可以很容易地转换它。 – 2010-10-25 00:37:12
有没有这样的运气?你可以在JavaScript中做同样的事情吗? – Baz1nga 2011-04-26 22:02:58