【Grasshopper】【Python】点集排序:带索引的Z字形排序算法
Grasshopper Python点集排序:带索引的Z字形排序算法
1. 功能介绍
这段代码实现了一个在Grasshopper中的点集排序功能,不仅可以将空间中的点按照Y坐标分组并在每组内按X坐标排序,还能追踪每个点的原始索引位置。
2. 输入输出参数
3. 核心算法流程
否
是
输入点集
点集是否为空?
创建点索引对
返回None
按Y坐标分组
组内按X排序
提取排序后的点
提取对应的索引
输出排序点集
输出索引列表
4. 代码解析
4.1 点索引对的创建和处理
points_with_index = list(enumerate(x))
enumerate()
创建(索引, 点)对4.2 分组函数
def groupPointsByY(points_with_index, tolerance):
points_with_index = sorted(points_with_index, key=lambda pair: pair[1].Y)
groups = []
current_group = [points_with_index[0]]
current_y = points_with_index[0][1].Y
4.3 分组逻辑
for p in points_with_index[1:]:
if abs(p[1].Y - current_y) <= tolerance:
current_group.append(p)
else:
groups.append(current_group)
current_group = [p]
current_y = p[1].Y
4.4 排序和结果提取
for group in grouped_points:
group_sorted = sorted(group, key=lambda pair: pair[1].X)
for index, point in group_sorted:
sorted_points.append(point)
sorted_indices.append(index)
5. Python语法要点
5.1 元组拆包
for index, point in group_sorted:
5.2 Lambda表达式
key=lambda pair: pair[1].X
5.3 列表操作
sorted_points.append(point)
sorted_indices.append(index)
6. 数据结构
6.1 点索引对
(index, point) 结构:
- index: 原始位置
- point: 点对象
- X: X坐标
- Y: Y坐标
- Z: Z坐标
6.2 分组结构
groups = [
[(index1, point1), (index2, point2), ...], # 第一组
[(index3, point3), (index4, point4), ...], # 第二组
...
]
左上角向右上角排序↗
# GH Python Component的设置:
# x: 输入点集(point list)
# t: 输入容差值(number),默认值可设为2000
# a: 输出排序后的点集(point list)
# i: 输出排序后点的原始索引(number list)
def groupPointsByY(points_with_index, tolerance):
"""将Y坐标相近的点分组"""
if not points_with_index:
return []
# 按Y坐标排序,注意points_with_index中的每个元素是(index, point)的元组
points_with_index = sorted(points_with_index, key=lambda pair: pair[1].Y)
groups = []
current_group = [points_with_index[0]]
current_y = points_with_index[0][1].Y # 使用pair[1]访问点
# 遍历所有点,根据Y坐标差值分组
for p in points_with_index[1:]:
if abs(p[1].Y - current_y) <= tolerance: # 使用pair[1]访问点
current_group.append(p)
else:
groups.append(current_group)
current_group = [p]
current_y = p[1].Y # 使用pair[1]访问点
groups.append(current_group)
return groups
if x: # 确保输入不为空
# 设置默认容差值
tolerance = t if t is not None else 2000
# 创建带索引的点列表
points_with_index = list(enumerate(x)) # 创建(索引, 点)对的列表
# 将点按Y坐标分组
grouped_points = groupPointsByY(points_with_index, tolerance)
# 对每组内的点按X坐标排序
sorted_points = []
sorted_indices = []
for group in grouped_points:
# 按X坐标排序,同时保持索引
group_sorted = sorted(group, key=lambda pair: pair[1].X) # 使用pair[1]访问点
# 分离点和索引
for index, point in group_sorted:
sorted_points.append(point)
sorted_indices.append(index)
a = sorted_points
i = sorted_indices
else:
a = None
i = None
左上角向右下角排序↘
# GH Python Component的设置:
# x: 输入点集 (point list)
# t: 输入容差值 (number),默认值可设为2000
# a: 输出排序后的点集 (point list)
# i: 输出排序后点的原始索引 (number list)
def groupPointsByY(points_with_index, tolerance):
"""将Y坐标相近的点分组,并按Y值从大到小排序,确保按从上到下进行分组"""
if not points_with_index:
return []
# 修改:按Y坐标从大到小排序(最高的点在前),reverse=True
points_with_index = sorted(points_with_index, key=lambda pair: pair[1].Y, reverse=True)
groups = []
current_group = [points_with_index[0]]
current_y = points_with_index[0][1].Y # 当前组参考的Y值
# 遍历剩余的点,若两点Y坐标差值在容差范围内,则归为一组
for p in points_with_index[1:]:
if abs(p[1].Y - current_y) <= tolerance:
current_group.append(p)
else:
groups.append(current_group)
current_group = [p]
current_y = p[1].Y
groups.append(current_group)
return groups
if x: # 确保输入不为空
# 设置默认容差值
tolerance = t if t is not None else 2000
# 为每个点创建一个(原始索引, 点)的元组列表
points_with_index = list(enumerate(x))
# 按Y坐标(从上到下)分组
grouped_points = groupPointsByY(points_with_index, tolerance)
sorted_points = []
sorted_indices = []
# 对每组内的点按X坐标从小到大排序(从左至右)
for group in grouped_points:
group_sorted = sorted(group, key=lambda pair: pair[1].X)
for index, point in group_sorted:
sorted_points.append(point)
sorted_indices.append(index)
a = sorted_points
i = sorted_indices
else:
a = None
i = None
作者:hmywillstronger