简体   繁体   English

给定一个点矢量(可能是乱序),找到多边形(不是凸包)

[英]Given a vector of points (possibly out of order), find polygon (not convex hull)

I currently have a vector of points 我目前有一个点矢量

vector<Point> corners;

where I have previously stored the corner points of a given polygon. 我以前存储过给定多边形的角点。 Given that, I know for sure that the points form a simple polygon that does not contain any self-intersecting edges. 鉴于此,我确信这些点形成了一个不包含任何自相交边的简单多边形。 However, in the process of storing these vertices, the order in which they connect to each other was not preserved. 但是,在存储这些顶点的过程中,不保留它们彼此连接的顺序。

I now have a function that, given a vector of points, connects them and draws me a closed figure. 我现在有一个函数,给定一个点矢量,连接它们并绘制一个封闭的数字。 However, I need to give this function the sequence of points in the order they need to be connected. 但是,我需要按照需要连接的顺序给这个函数一系列点。 Can anyone suggest a way that I could sort these points in the correct order? 任何人都可以提出一种方法,我可以按正确的顺序对这些点进行排序吗? They form a very simple concave polygon, not a convex hull. 它们形成一个非常简单的凹多边形,而不是凸包。 An algorithm to find the center point among all the (7) points would also be helpful :) 在所有(7)点中找到中心点的算法也会很有帮助:)

There is no unique solution for a concave polygon: 凹多边形没有唯一的解决方案:

在此输入图像描述

The convex polygon could be find uniquelly as the convex hull of the points (if you know that the points build a convex polygon). 凸多边形可以作为点的凸包发现不均匀(如果你知道这些点构建一个凸多边形)。

A given set of points can generally be joined up many ways to form a non-self-intersecting polygon. 一组给定的点通常可以通过多种方式连接以形成非自相交的多边形。 You may be out of luck unless you have more information about the kinds of polygons the points could represent. 除非您有关于点可能代表的多边形种类的更多信息,否则您可能会失败。

1. Heuristic to determine the shape 1.启发式确定形状

There is no unique solution so there is no simple algorithm. 没有独特的解决方案,因此没有简单的算法。 You could try to somehow mimic your intuition. 你可以尝试以某种方式模仿你的直觉。

  • start by a random point and connect each point to its closest neighbor. 从随机点开始,将每个点连接到最近的邻居。 Then connect the last point to the first one. 然后将最后一个点连接到第一个点。
  • start by selecting a point and its closest neighbor and connect them by a line. 首先选择一个点及其最近的邻居,然后用一条线连接它们。 Now iteratively add another point. 现在迭代地添加另一个点。 Always select the point which minimizes the angle between the last line segment and the newly added line segment. 始终选择最小化最后一个线段与新添加的线段之间角度的点。

Both methods don't really work in general, they don't even guarantee to avoid intersections. 这两种方法一般都不起作用,它们甚至不能保证避免交叉。 You can try to address this by backtracking, if you detect an obvious error (eg an intersection) then backtrack to the last point of decision and take the "second best" approach instead, .... 你可以尝试通过回溯来解决这个问题,如果你发现了一个明显的错误(例如一个交叉点),那么回溯到最后一个决策点并采取“第二好”的方法,....

But again as the solution is not unique, don't expect too much from those heuristics. 但是,由于解决方案不是唯一的,所以不要期望从这些启发式方法中获得太多。

2. Average of the vertices 2.顶点的平均值

The average point for the vertices is easy to compute. 顶点的平均点很容易计算。 Just add all points together and divide through the number of points you just added, this is the average. 只需将所有点加在一起,然后除以刚刚添加的点数,这就是平均值。 What you are probably more interested is the center point in the sense of "Center of mass", see below. 你可能更感兴趣的是“质心”意义上的中心点,见下文。

3. Center point 3.中心点

To determine the center of mass you first have to define the shape. 要确定质心,首先必须定义形状。 That means you have to do something like step 1. 这意味着你必须做类似第1步的事情。

An easily implemented method to compute the center point given the polygon is. 给定多边形计算中心点的一种简单实现的方法是。

  • Put a bounding box around the polygon. 在多边形周围放置一个边界框。
  • Randomly generate points inside the bounding box. 在边界框内随机生成点。
  • For each of those points determine if it is inside the bounding box, if not, then throw it away. 对于每个点确定它是否在边界框内,如果没有,则将其丢弃。 To determine if a point is inside an arbitrary polygon use a ray test . 要确定某个点是否在任意多边形内,请使用光线测试
  • For all points that you kept, apply approach 2. The Average point of those points is a good approximation to the center point. 对于您保留的所有点,应用方法2.这些点的平均点是对中心点的良好近似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM