[英]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.