对点进行排序和分组

时间:2016-04-01 00:41:38

标签: c# sorting computational-geometry

我有一个相当简单的对象,其形状由12个顶点定义。当对此对象进行隐藏线计算时(我使用Cad Control执行此操作),它返回构成形状的线条集合,通常比绘制此类形状的最小线条数量多得多,请参阅附图: enter image description here

点之间的每个段都是一条线。我想删除用红色标记的点,只留下绘制形状所需的最小计数(黄色十字)。

一种方法是顺时针对它们进行排序,然后循环检查它们,检查列表中三个相邻点的叉积是否为零,然后删除中间点。不幸的是,无法预测如何对点进行排序,因此这不是一种选择。

第二种方法是循环访问由cad控制提供的行集合,并查找同一行上的所有点,对它们进行排序(pointsLineA,pointsLineB,pointsLineC等)从那里可以更容易。< / p>

到目前为止,我已经完成了循环遍历行集合(获取每个行点)并在嵌套循环中循环遍历相同的集合(它的副本)以检查集合中任何随机行的点是否位于与来自第一个循环的行的点相同的行。这涉及两个循环并在运行时修改集合。简而言之,它是一个MESS。如果您想查看代码示例,请告诉我。 为了确保一切都清楚 - 我的第一个目标是对点进行分组,以便在每个组中出现仅属于一行的点。有什么建议?

2 个答案:

答案 0 :(得分:0)

有12个顶点(或数百个顶点),我不会进行空间分区(我考虑自适应四叉树,2D树(k = 2,k = 2))。 我为每个顶点存储它所属的行(它更容易为每个顶点和行分配ID,而不是每次比较顶点的坐标)。

vertex(1)=(2.5,3.97)  <- vertex coordinates
vertex(2)=( 13.453 , 24.687 ) 

lines_for_Vertex(1)= {1,5} if vertex 1 is member of lines 1 and 5
lines_for_Vertex(3)={2,5,7} if vertex 3 is member of lines 2,5 and 7
lines_for_vertex(9)={4} if vertex 9 is member of line 4 (edge or segment not connected)
lines_for_vertex(3)={} if vertex 3 is not connected (not member of any segment)
(maybe some cases are impossible for you)

您可以将ID分配给行集合中位置的行。

在任何情况下,如果您执行此更改或保留您的行集合,则在嵌套循环内您必须收集要删除的点的信息而不更改任何内容。 所以不要这样做:

if vertices are aligned then remove the vertex in the middle

你填写一份清单&#39; to_remove&#39;有了这些信息:

to_remove.add(vertex in the middle)         <- with the ID is easier

然后当两个循环结束时,您可以删除列表中收集的所有顶点。如果你有数组&#39; lines_for_vertex&#39;很容易找到要折叠成一个的两个段(例如,如果要删除的顶点是1,则折叠线是1和5)。

如果你甚至为线构建一个结构,参考其顶点的ID

e.g. line(5)={1,3} if line with ID=5 connects vertices 1 and 3 

(与上面的lines_for_vertex相比),它更容易知道如何折叠线。

答案 1 :(得分:0)

您需要检索多边形的拓扑。在闭环中重新排列顶点的方法。通过比较端点坐标,您可以找到匹配并获得端点之间边缘的图形,并合并端点。

通过此表示,您可以轻松检测并删除对齐。