【问题标题】:How to sort a random array of points into a shape?如何将随机点数组排序成一个形状?
【发布时间】:2023-01-24 23:28:13
【问题描述】:

我有一个随机的点阵列,形成这样的形状:

但是它以这样一种方式出现,即构成它的点(坐标)随机分布在一个数组中。

我如何对它们进行排序以使它们连续(数组中的每一对连续点对应于形状中的一对连续点)?

编辑:应该更好地解释它。

我们尝试使用点的某种顺时针方向,但它在边缘和背面的直线处中断。 某种种子,其中最低的 X 点是起点,最近的点附加到它。也在边缘处中断,最近的点不需要连续的点。 如果我将上部和下部分开(使用最低的 X 点作为 Y 标准),并分别对两个数组进行排序,凹面部分也会破坏它。

这些点来自 .dat 文件,其中每行是 2 个数字,以空格分隔:

2.345 1.234
1.234 2.345

【问题讨论】:

  • 你试过什么了?
  • 什么是“点”?一个二元组?自定义数据结构?特定于图书馆的课程?
  • 您最初是如何生成这些点的?
  • 是否可以假设给定 3 个连续点 A、B、C,那么不存在点 X,使得 B 和 X 之间的距离小于 A 和 B 之间的距离以及 B 和 C 之间的距离?
  • 它在边缘断开,因为数组没有足够的形状信息。有点...如果它坏了并且点错了顺序,那只是你认为它是不正确的,但它仍然是一种形状,只是一种不同的形状。似乎不能以普遍的方式完成。您可以在这里使用一些启发式方法,但在 100% 的情况下它不会准确。

标签: python point-clouds


【解决方案1】:

根据这个答案:https://cs.stackexchange.com/a/52627你可以使用格雷厄姆扫描凸包算法的一部分。

格雷厄姆扫描的第一步是根据点和集合右下角画线时与 X 轴形成的角度对集合中的点进行排序。

如果两个或多个点与 X 轴形成相同的角度(即相对于参考点对齐),则应根据与参考点的距离对这些点进行排序。

import dataclasses
from functools import cmp_to_key


@dataclasses.dataclass
class Point:
    x: float
    y: float


def left_(p: Point, a: Point, b: Point) -> float:
    return (a.x - p.x) * (b.y - p.y) - (b.x - p.x) * (a.y - p.y)


def compare_angle(p: Point, a: Point, b: Point) -> float:
    left = left_(p, a, b)
    if left == 0:
        return compare_distance(p, a, b)
    return left


def compare_distance(p: Point, a: Point, b: Point) -> float:
    distance_a = (p.x - a.x) ** 2 + (p.y - a.y) ** 2
    distance_b = (p.x - b.x) ** 2 + (p.y - b.y) ** 2
    return distance_a - distance_b


def sort_points(points: list[Point]):
    y0 = min(map(lambda p: p.y, points))
    p0 = Point(
        y=y0,
        x=max(map(lambda p: p.x, filter(lambda p: p.y == y0, points)))
    )
    return sorted(points, key=cmp_to_key(lambda a, b: compare_angle(p0, a, b)))

尽管如此,它仍然有一些限制,所以它可能不会在 100% 的情况下完美,因为形状可能太复杂了。我认为,它会以均匀的点分布来完成工作,并且当与形状大小相比有相当数量的点时,但如果会有一些复杂的形状,点之间有长边,形状部分之间的关​​闭调用等., 可能会出错。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-30
    • 2014-03-21
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多