代码之家  ›  专栏  ›  技术社区  ›  Hao Wooi Lim

找到不规则(非凸)形状的稳定位置

  •  10
  • Hao Wooi Lim  · 技术社区  · 14 年前

    给定一个二维不规则(非凸)形状的图像,我如何能够计算出它在平面上稳定的所有方式?例如,如果形状是一个完美的矩形,那么它肯定有四种稳定的方式。另一方面,圆要么没有稳定的方向,要么每个点都是稳定的方向。

    编辑:有一个很好的小游戏叫 Splitter (当心,上瘾的游戏)这似乎接近我想要的。注意到你切了一块木头,它会掉到地上,并以稳定的方式躺在地上。

    编辑:最后,我采用的方法是计算重心(形状),计算凸壳(使用opencv),然后循环遍历每对顶点。如果重心落在2个顶点形成的线的顶部,则认为它是稳定的,否则,不是。

    3 回复  |  直到 14 年前
        1
  •  9
  •   walkytalky    13 年前

    首先找到它的质心(cm)。一个稳定的位置就是厘米 较高的 如果你稍微旋转一下。现在看看外壳,包围形状的最小凸起区域:

    Convex Hull and Centre of Mass http://walkytalky.net/extern/hull.png

    如果船体是一个多边形,那么一个稳定的位置就是形状停留在其中一个边上,而cm直接在该边上(不一定在该边的中点上,就在它上面的某个地方)。

    如果船体有曲线(也就是说,如果形状有与船体接触的曲线),必须对其进行特殊处理。如果cm位于曲线最低点正上方,且曲线在该点的半径大于cm的高度,则形状将稳定在曲线边缘上。

    实例:

    1. 长方形。船体只是一个长方形,厘米在中间。四个侧面的形状都很稳定。
    2. 一个两边都被挖空了的长方形,但角部仍然完好无损。船体仍然是原来的矩形,厘米接近它原来的位置。船体的四个侧面都是稳定的(也就是说,你仍然可以把形状放在任意两个角上)。
    3. 一个圆圈厘米在中心,船体是圆的。没有稳定的位置,因为曲线的半径总是等于厘米的高度。轻轻碰一下,它就会滚动。
    4. 椭圆厘米在中心,船体是形状。现在有两个稳定的位置。
    5. 半圆厘米在对称轴的某个地方,船体就是形状。两个稳定位置。
    6. 一个狭窄的半圆新月。船体是一个半圆,厘米在外形之外(但在船体内部)。两个稳定位置。

    Illustration of the examples http://walkytalky.net/extern/stable.png

    (标有x的椭圆位置不稳定,因为曲率小于到质心的距离。)

        2
  •  3
  •   Justin L.    14 年前

    注意:这个答案假设你的形状是一个正确的多边形。

    为了我们的目的,我们将平衡位置定义为 质心在物体最左侧和最右侧地面接触点之间的点正上方。 (假设地面是垂直于重力的平面)。这在所有情况下都适用,适用于所有形状。

    注意,这实际上是 physical definition 由于牛顿转动运动学,转动平衡。

    对于一个适当的多边形,如果我们消除它们位于唯一顶点上的情况,这个定义就相当于一个稳定的位置。

    所以,如果你有一个垂直向下的重力,首先要找到它最左边和最右边接触地面的部分。

    然后,计算质心。对于具有已知顶点和 均匀密度 ,这个问题被简化为 Centroid ( relevant section )

    然后,从你的COM上放一条线;如果COM和地面的交点在这两个x值之间,它就处于平衡状态。

    如果最左边的点和最右边的点匹配(例如,在一个圆形的对象中),这仍然有效;记住要小心浮点比较。

    注意,这也可以用来测量物体的“多稳定”——这是质量中心在不在两个接触点范围内之前可以移动的最大Y距离。

    编辑:仓促制作的精美图表

    Diagram http://img52.imageshack.us/img52/9506/1276930988102131dc.png

    那么,你怎么能用它找到所有可以坐在桌子上的方法呢?见:


    编辑

    可编程方法

    而不是旋转形状的计算代价昂贵的任务,试试这个。

    程序中形状的表示形式可能包含所有顶点的列表。

    查找形状的顶点 convex hull (基本上是你的形状,但是所有的凹顶点——被“推入”的顶点——都被消除了)。

    然后遍历凸壳上的每对相邻顶点(即,如果我有顶点A、B、C、D,我将遍历AB、BC、CD、DA)

    做这个测试:

    1. 画一条线 通过测试两个顶点
    2. 画一条垂直于 ,通过COM C .
    3. 求两条线的交点(简单代数)
    4. 如果交集的y值在两个顶点的y值之间,则它是稳定的。如果y值都相等,请比较x值。

    这应该能解决问题。

    下面是在一对顶点上运行测试的示例:

    Example test http://img17.imageshack.us/img17/918/stabled.png

    如果您的形状不是由它在数据结构中的顶点表示的,那么您应该尝试转换它们。如果它类似于一个圆或一个椭圆,你可以用试探法来猜测答案(一个圆有无限的平衡位置;一个椭圆4,尽管只有两个“稳定”点)。如果它是一个弯曲而不规则的形状,你必须提供你的数据结构,以便我能够以一种与程序相关的方式提供帮助,而不仅仅是提供个案启发。

        3
  •  0
  •   Jamie Wong    14 年前

    我相信这不是最有效的算法,但这是一个想法。

    如果可以对多边形的垂直线进行排序(假设其顶点数目有限),那么只需迭代相邻的顶点对,并通过某种形式的模拟记录其所处的角度。在像星星这样的奇怪形状的情况下,它会有重复的方向,但是你可以通过跟踪静止的旋转来适应它。