用户绘制圆的凸包

时间:2019-05-18 17:06:44

标签: c# algorithm computational-geometry convex-hull

我正在开发一款游戏,其中我必须找到一组凸点的凸包。我正在尝试选择正确的算法。这些点集是用户绘制的形状,因此它们具有顺序。理想情况下,用户绘制椭圆,但是只要是单个笔划,他们就可以绘制任何东西。下面是一些示例:

Different user-drawn shapes.

我想找到这些形状的凸包。我发现的所有凸包算法都假设一个随机无序的点集。当用户通过单击并拖动鼠标绘制点时,哪种算法最适合我的特定情况,因此这些点是有序的。

注意:

特别是,许多是输出敏感算法。 O(n log h),其中n是所有点集(原始点)中的点数,h是凸包中的点集。对于这些形状,我希望h〜= n,因为它们基本上是它们自身的轮廓。

最后,此方法的总体目标是找到这些点的最小面积矩形,例如:

enter image description here

除了首先找到凸包之外,还有谁能想到找到矩形的更好方法?经过研究,这似乎是最好的方法,但是我的特殊情况可能有所不同。

提前谢谢!

3 个答案:

答案 0 :(得分:2)

远离使用O(N Log H)算法。他们既困难又缓慢!

使用O(N Log N)是更好的选择。我建议您轻松快捷地使用monotone chain方法。

您不必担心复杂度顺序O(N Log N),这仅是由于排序阶段而已。额外的Log N / Log H因子不是那么灾难性(凸点集不存在),而排序的渐近常数非常好。

如果您追求最高效率,则点的特定排列方式建议使用另一种方法:这些点将形成长的递增(递减)序列,您可以通过合并步骤轻松地对其进行检测和排序。复杂度下降到O(N Log K),其中K是单调序列的数目,因此实际上是O(N)(这称为自然合并排序)。

与Melkman O(N)算法的用例相距不远,该算法可用于简单多边形的船体。不幸的是,简单性条件可能会在曲线的闭合附近失效,并且我认为没有简单的方法可以解决该问题。


对于边界矩形,旋转卡尺绝对是您最好的朋友。

答案 1 :(得分:0)

要找到在特定方向上对齐的最小封闭矩形,您需要知道该方向和正交方向上的极端点,凸包以一种特别方便的方式(例如旋转卡尺)对这些信息进行编码。如果您愿意近似,则可以每5度(或任意角度)尝试一次方向,运行时间为O(nd),其中d是方向数。如果您有SIMD支持,那么它可以很好地工作。

答案 2 :(得分:0)

我只是想知道如果应用以下方法会发生什么:

将多边形视为2 x N矩阵

inets

其中每列包含多边形顶点的x和y坐标。然后,针对说P = [x1, x2, ..., xN; y1, y2, ..., yN]; phi之间的任何角度0定义旋转矩阵

pi/2

然后,通过乘以矩阵将多边形旋转到phi角

U(phi) = [cos(phi) -sin(phi);
          sin(phi)  cos(phi)];

然后是功能

P_phi = U(phi)*P;

是水平和垂直边缘的矩形区域,在旋转的多边形f(phi) = ( max( P_phi[1][] ) - min( P_phi[1][] ) )*( max( P_phi[2][] ) - min( P_phi[2][] ) ) 周围重叠。这里P(phi)是矩阵P_phi的x坐标的第一行,P_phi[1][]是y坐标的第二行。 因此,您要查找角度对齐的矩形的角度P_phi[2][]和在2 x 4矩阵phi中收集的顶点,该矩形给出函数的最小值 R_phi代表f(phi),因为这是在多边形周围叠加的最小面积矩形的面积。找到phi in [0, pi/2]phi之后 如下旋转 R_phi,这是您要寻找的矩形。

我不确定该建议是否有效...