簡體   English   中英

如何將隨機點數組排序成一個形狀?

[英]How to sort a random array of points into a shape?

我有一個隨機點數組 forms 形狀如下:

在此處輸入圖像描述

但是它以這樣一種方式出現,即構成它的點(坐標)隨機分布在一個數組中。

我如何對它們進行排序以使它們連續(數組中的每一對連續點對應於形狀中的一對連續點)?

編輯:應該更好地解釋它。

我們嘗試使用點的某種順時針方向,但它在邊緣和背面的直線處中斷。 某種種子,其中最低的 X 點是起點,最近的點附加到它。 也在邊緣處中斷,最近的點不需要連續的點。 如果我將上下分開(使用最低的 X 點作為 Y 標准),並分別對 arrays 進行排序,凹面部分也會破壞它。

這些點來自 a.dat 文件,其中每行是 2 個數字,以空格分隔:

2.345 1.234
1.234 2.345

根據這個答案: https://cs.stackexchange.com/a/52627你可以使用格雷姆掃描凸包算法的一部分。

Grahm Scan 的第一步是根據通過點和集合右下角畫線時與 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% 的情況下完美,因為形狀可能太復雜了。 我認為,它會以均勻的點分布來完成工作,並且當與形狀大小相比有相當數量的點時,但如果會有一些復雜的形狀,點之間有長邊,形狀部分之間的關閉調用等., 可能會出錯。

PS:當我在評論中說計算機不知道正確的形狀所以它可能是錯誤的時,我的意思是:

兩者都是相同的點,並且都是數學上正確的非自相交多邊形例子

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM