如何用凸形形状形成凹形?

时间:2011-07-13 22:06:53

标签: c++ math graphics sfml concave

我试图绕过只能在SFML c ++库中形成凸形的规则。

  

要做到这一点,我打算测试给定的顶点,如果是凹的,   将顶点分成组,测试每组的凹度,   然后重复,直到看到一整套凹形   就像放在一起时的原始形状一样

我想知道的是......

  • 测试形状凹度的等式是:它是什么以及它是如何工作的?

  • 如何分割凹形的顶点,以便最终形状尽可能少的凸形?

  • 实现目标的最佳做法是什么?

谢谢!


5 个答案:

答案 0 :(得分:6)

您可以通过绕过所有边缘并检查下一个边缘是否始终沿同一方向(左/右手)移动来测试形状为凸包的形状。这是一种快速而廉价的算法。这里有一个实现:en.wikipedia.org/wiki/Graham_scan

如果您没有凸包,请执行包裹算法以获得包含所有点的凸包(再次非常快)。 en.wikipedia.org/wiki/Gift_wrapping_algorithm

现在,寻找你的形状上的点,但不在凸包上。对于这些点的每次运行,从这些点创建一个新形状(加上凸包的两侧)。

递归现在是你的朋友:对刚刚制作的每个子形状执行完全相同的处理。

我已经使用这种技术测试一个包含在任意形状内的点:即该点必须在凸包内(易于测试),但不是任何子形状或它们的子形状,或他们的子形状......

答案 1 :(得分:4)

Boost Geometry library published yesterday,实施 Convex Hull algorithm 。一张图片说了千言万语:

enter image description here

虽然这个构造一个非凹的“新”形状(即凸起);这可能正是您想要的,也可能不是。但是,在这个过程中算法绑定能够将形状分类为凹/凸,所以你可能会对图书馆感兴趣。

凸壳算法的一般信息:


由于Adrian Japon或多或少地建议“打击测试”(包容测试)是关心凸/凹几何的常用理由,不再赘述,我将突出显示相应的Boost几何算法: within 即可。

  

再次,真的因为画面太漂亮了。请注意,尽管图片建议查询多边形的点,但算法完全通用,可用于测试另一个 n - 维多边形的完整包含 < / p>

enter image description here

答案 2 :(得分:3)

好的,只是将所有信息混合在一起:

  • 要测试多边形凹面,请查看Adrian提供的this page 泰勒
  • 实现目标的一种方法是使用Monotone Decomposition and Triangulation
  • 您可以在this lovely site了解单调分解:(摘要如下)

img 1

  • 最后,使用this Powerpoint中的信息对现在的Monotone形状进行三角测量:

    1. 将u1和u2推入堆栈。
    2. j = 3 / * j是当前顶点的索引* /
    3. u = uj
    4. 案例(i):u与v1相邻但不与vi相邻。     添加对角线uv2,uv3,...,uvi。     来自堆栈的pop vi,vi-1,...,v1。     推vi,你在堆栈上。 情况(ii):u与vi相邻但不与v1相邻。     而我&gt; 1和角度uvivi-1&lt;          添加对角线uvi-1         来自堆栈的pop vi     ENDWHILE     推你 情况(iii):u与v1和vi相邻。     添加对角线uv2,uv3,...,uvi-1。     出口
    5. j = j + 1 转到第3步。

**Note:**
By “adjacent” we mean connected by an edge in P.   
Recall that v1 is the bottom of the stack, vi is the top.    
By “Push” we mean push the item(s) to the back of the list    

希望这有助于某些人...但我仍在寻找更好/更快的解决方案。

答案 3 :(得分:1)

要考虑的一些事情:

  • 左撇子和右撇子角(交叉产品的标志是一种容易区分的方式)。凸起形状的所有角都是相同的手。

  • 扩展边缘并添加新顶点可能比在现有顶点之间添加边缘提供更好的结果。

答案 4 :(得分:1)

我假设您将多边形作为点列表,一种非常简单的方法是绕过多边形并考虑连续点(A,B,C)的三元组序列。

然后你只需检查一下det(AB,BC)改变其符号,其中

det(AB,AC)=(x_a-x_b)(yc-yb) - (x_c-x_b)(y_a-y_b)