我正在寻找一种方法来计算单个矩形与一小组矩形的并集之间的交叉区域。
我正在使用Java,所有矩形都以整数(x,y,w,h)表示。所有矩形都与x / y轴轴对齐。 有什么建议吗?
答案 0 :(得分:1)
你可能在Rect1和RectSet联合中的每个矩形之间有一个唯一的交集。因此,您将分别在Rect1和union中的每个矩形之间进行交集。相交区域是Rect1和联合中矩形之间所有相交部分的并集。
优化是为矩形的并集创建一个丰富的矩形(希望在创建联合时完成)。如果Rect1不与此边界矩形相交,则可以跳过任何进一步的交叉点,并将该区域设为null。
答案 1 :(得分:1)
两个矩形的交集是一个矩形本身(可能是退化的,但那些面积为零,可以忽略)。此外,联合的交集与交叉的联合(分配定律)相同。因此,您可以将R1与每个Rj相交,并找到结果矩形的并集。
要找到联合,最简单的方法可能是通过在每个顶点绘制一条垂直线将场景分解为垂直条纹。然后在每个条纹中,这是一个众所周知的一维问题,通过计数入点和出点以及删除计数大于1的点来解决。
答案 2 :(得分:1)
通过并表示你的矩形不是(x,y,w,h),而是表示(x1,y1,x2,y2),它们只是(x,y,x + w,y + h)。 / p>
然后,遍历所有Rj`s并将矩形“剪辑”到Rect1的坐标:
Rj.x1 = max(Rj.x1, Rect1.x1)
Rj.y1 = max(Rj.y1, Rect1.y1)
Rj.x2 = min(Rj.x2, Rect1.x2)
Rj.y2 = min(Rj.y2, Rect1.y2)
现在,通过并删除Rj.x1>=Rj.x2
或Rj.y1>=Rj.y2
所在的任何Rj,就像在这种情况下,矩形不相交。
之后,总结其余矩形的所有区域(只需(Rj.x2-Rj.x1) * (Rj.y2-Rj.y1)
)。
此时,您将对任何剪裁的Rj重叠的任何区域进行双重计数。
所以,你需要经过并循环遍历所有Ri和所有Rj,其中j> i,并将两者夹在一起,但这次,如果有一个交叉点(与上面相同的测试),你需要从目前为止的值中减去交点的面积,以消除重复计算。
不幸的是,这将双重删除三重叠的任何区域。因此,您需要找到这些区域并将它们重新添加进去。依此类推四重叠,五重叠等等。
听起来会变得非常混乱......
也许最简单的方法是将Rj绘制成红色的画布,然后计算最后Rect1内的红色像素。 (当然,您不必使用真正的Canvas。您可以使用位数组编写自己的。)甚至可能有一些场景(比如一个带有很多小矩形的小坐标空间),这比分析解决方案。但是,当然只有你有整数坐标时才会有效。
答案 3 :(得分:0)
n.m's answer和PQuinn's answer都建议在整个联合中分配交集,然后找到联合的区域。这是一个好主意。
在java中,我建议在R1和你的Rj之间创建一组新的非退化交叉点,这是基于大多数交叉点将退化的假设。然后使用http://codercareer.blogspot.com/2011/12/no-27-area-of-rectangles.html处的算法查找交叉点集的区域。