【问题标题】:Algorithm to find all convex quadrilaterals from the given list of 2d points从给定的二维点列表中找到所有凸四边形的算法
【发布时间】:2012-12-20 20:20:17
【问题描述】:

我必须编写一个程序来从给定的二维点列表中找到所有凸四边形。 我已经尝试过使用矢量叉积,但它似乎不是一个正确的解决方案。

也许有一些有效的算法可以解决这个问题,但我找不到。

这是一个输入和输出的例子:

输入

点数: 6 点坐标(x,y): 0 0 0 1 1 0 1 1 2 0 2 1

输出

凸四边形的数量: 9

【问题讨论】:

  • 你的意思是凸多边形吗?如果它们是四边形(4 面),我不清楚为什么要指定多个点。
  • 哦,是后面列表中的点数,是吗?
  • 无论如何,我认为您可以通过检查第 4 个点是否在前三个点定义的三角形之外来检查 4 个点是否是凸四边形的顶点。
  • 对不起,这是凸四边形的个数。谢谢建议。

标签: algorithm geometry computational-geometry


【解决方案1】:

一个四边形是凸的,如果它的对角线相交。反之,如果两条线段相交,则它们的四个端点构成一个凸四边形。

每一对点给你一条线段,两条线段之间的每一个交点对应一个凸四边形。

您可以使用比较所有分段对的朴素算法或Bentley–Ottmann algorithm 找到points of intersection。前者取 O(n4);而后者 O((n2 + q) log n) (其中 q em> 是凸四边形的数量)。在最坏的情况下q = Θ(n4)——考虑一个圆上的n个点——所以Bentley—— Ottmann 并不总是更快。

这是 Python 中的原始版本:

import numpy as np
from itertools import combinations

def intersection(s1, s2):
    """
    Return the intersection point of line segments `s1` and `s2`, or
    None if they do not intersect.
    """
    p, r = s1[0], s1[1] - s1[0]
    q, s = s2[0], s2[1] - s2[0]
    rxs = float(np.cross(r, s))
    if rxs == 0: return None
    t = np.cross(q - p, s) / rxs
    u = np.cross(q - p, r) / rxs
    if 0 < t < 1 and 0 < u < 1:
        return p + t * r
    return None

def convex_quadrilaterals(points):
    """
    Generate the convex quadrilaterals among `points`.
    """
    segments = combinations(points, 2)
    for s1, s2 in combinations(segments, 2):
        if intersection(s1, s2) != None:
            yield s1, s2

还有一个示例运行:

>>> points = map(np.array, [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)])
>>> len(list(convex_quadrilaterals(points)))
9

【讨论】:

  • 通过您的示例,我得到: ValueError: 具有多个元素的数组的真值是不明确的。使用 a.any() 或 a.all()
  • @LudoSchmidt:您使用的 NumPy 版本可能比我在 2012 年 12 月使用的版本更新
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多