当前位置: 首页 > news >正文

【Grasshopper】【Python】点集排序:带索引的Z字形排序算法

Grasshopper Python点集排序:带索引的Z字形排序算法

在这里插入图片描述

1. 功能介绍

这段代码实现了一个在Grasshopper中的点集排序功能,不仅可以将空间中的点按照Y坐标分组并在每组内按X坐标排序,还能追踪每个点的原始索引位置。

2. 输入输出参数

  • 输入参数:
    • x: 待排序的点集(Point List)
    • t: 容差值(Number),默认2000
  • 输出参数:
    • a: 排序后的点集(Point List)
    • i: 排序后点的原始索引(Number List)

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
  • 函数接收点索引对和容差值
  • 使用lambda函数访问点的Y坐标进行排序
  • pair[1]访问点对象,pair[0]访问索引

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
  • 遍历点索引对
  • 基于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)
  • 组内按X坐标排序
  • 分别提取点和索引
  • 维护排序后的两个列表

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)
  • 使用append()逐个添加元素
  • 维护两个平行列表

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

相关文章:

  • MySQL配置文件读取顺序
  • 【故障处理】- 11g数据泵到19c导致的job不自动执行
  • Golang学习笔记_34——组合模式
  • 什么是语料清洗、预训练、指令微调、强化学习、内容安全; 什么是megatron,deepspeed,vllm推理加速框架
  • 【Scrapy】Scrapy教程6——提取数据
  • 30 款 Windows 和 Mac 下的复制粘贴软件对比
  • MySQL数据库基础
  • 分享8款AI生成PPT的工具!含测评
  • 如何最优雅地部署 AWS Lambda?Lambda Version 与 Alias 的最佳实践
  • 玩转文档处理,Docling 让一切变得简单
  • Java常用设计模式及其应用场景
  • PyCharm无法识别conda环境
  • Python 日志记录全解析:从入门到进阶的实用指南
  • 【深度学习】基于MXNet的多层感知机的实现
  • 【深度学习】如何一步步实现SGD随机梯度下降算法
  • 本地DeepSeek模型GGUF文件转换为PyTorch格式
  • ubuntu24 springboot jar设置宕机重启
  • App接入图表:MPAndroidChart,如何创建柱状图、双柱状图以及折线图
  • Python的顺序结构和循环结构
  • 个人博客测试报告
  • 重庆荣昌出圈背后:把网络流量变成经济发展的增量
  • 铲屎官花5万带猫狗旅行,宠旅生意有多赚?
  • 苹果Safari浏览器上的搜索量首次下降
  • 习近平出席俄罗斯总统举行的欢迎仪式
  • 纪念苏联伟大卫国战争胜利80周年阅兵彩排,解放军仪仗队亮相
  • 中方对原产印度进口氯氰菊酯实施反倾销措施,商务部回应