我有一组具有相同宽度和高度的矩形,并且始终是adiacent。 我知道所有顶点的位置,每个顶点只有4个(因为是正方形)。
此图片可以解释为:
如果有任何差距,如果算法将“填补”差距,则可以。
我搜索了很多,找不到任何好的东西.. 我需要一个简单的算法,它不一定非常有效.. 假设我们从图像中获得了第二个多边形示例中的7个矩形。 如果我首先将1与2合并,然后将我们的新多边形与3合并,那么就可以了,依此类推,它不一定非常快,因为最多会有50个矩形。
答案 0 :(得分:5)
因为你的形状只是由矩形组成而且它们总是相邻的,所以合并的算法比没有这些假设的算法简单得多。
Edge
成为具有正确定义的compareTo()
和equals()
的类。compareTo
)。答案 1 :(得分:3)
我真的很喜欢Dariusz答案的效率。它可能会满足您的所有要求,在这种情况下也可以使用它。
然而,有一些问题浮现在脑海中。
合并后有多种形状怎么办?如何检测这些形状是分开的还是嵌套的?就此而言,如果简单地给出一组边缘,则不容易判断它是否构成形状,或者是否留在形状内部。
例如,在合并相邻的正方形后考虑下图:
+----------------+
| |
| +------------+ |
| | | |
| | +--------+ | |
| | | | | |
| | | | | |
| | +--------+ | |
| | | |
| +------------+ |
| |
+----------------+
这里有2个形状 - 1个在另一个里面。但是,有3组连接边。为了查看内部矩形是形状还是形状中的空白,您必须从外部矩形开始向内工作。这样做将导致知道形状基本上是围绕另一个矩形的矩形的轮廓。但是,如果要移除外边缘,则生成的形状将只是一个空心矩形 - 一个形状。
假设这与您的问题相关(可能不是),那么以下算法可能更合适:
不要在开头将所有矩形的所有边缘的集合放在一起,而是将每个矩形分开放在Polygon
的列表中。每个Polygon
都有自己的一组边。
合并此列表中的Polygon
共享边缘,直到您留下一组不同的Polygon
s(即不再进行合并)。
List<Polygon> plist;
// Populate the list with the polygons...
for (int i=0; i<plist.size(); i++) {
Polygon p1 = plist.get(i);
boolean distinct = false;
while (!distinct) {
distinct = true;
for (int j=plist.size()-1 ; j>i; j--) {
Polygon p2 = plist.get(j);
if (p1.sharesEdge(p2)) {
// Merge the two polygons
p1.merge(p2);
// One less shape
plist.remove(j);
distinct = false;
} // if (p1.sharesEdge(p2))
} // for (int j=plist.size()-1 ; j>i; j--)
} // while (!distinct)
} // for (int i=0; i<plist.size(); i++)
最后,您将在Polygon
中找到单独plist
的列表。
sharesEdge
只是循环遍历每个Polygon
的边缘,看看它们是否有任何共同之处。
merge
与Dariusz的答案完全相同 - 删除边缘对。
一些假设 - 所有初始多边形都具有单位长度的边。如果不是这样,那么您可能需要在合并时拆分边缘并使用更复杂的方法检查共享边。
如果需要通过将嵌套形状吸收到更大的形状(即填充间隙)来处理嵌套形状,那么它会变得有点棘手。您首先要创建边的路径。如果边缘全部连接,则这是一个简单的形状,其边缘定义周边。如果没有,则应该有一个外周边和一个或多个内周边。忽略内周边并将形状解析为简单 - 即仅保留外周边的边缘。然后,在形状上循环,看看是否有任何形状在另一个内部。如果是这样,请将其删除。