主页 > 创业  > 

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

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

1. 功能介绍

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

2. 输入输出参数 输入参数: x: 待排序的点集(Point List)t: 容差值(Number),默认2000 输出参数: a: 排序后的点集(Point List)i: 排序后点的原始索引(Number List) 3. 核心算法流程 #mermaid-svg-HuuoVyU3BNNqoAjd {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-HuuoVyU3BNNqoAjd .error-icon{fill:#552222;}#mermaid-svg-HuuoVyU3BNNqoAjd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HuuoVyU3BNNqoAjd .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-HuuoVyU3BNNqoAjd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HuuoVyU3BNNqoAjd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HuuoVyU3BNNqoAjd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HuuoVyU3BNNqoAjd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HuuoVyU3BNNqoAjd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HuuoVyU3BNNqoAjd .marker.cross{stroke:#333333;}#mermaid-svg-HuuoVyU3BNNqoAjd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HuuoVyU3BNNqoAjd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HuuoVyU3BNNqoAjd .cluster-label text{fill:#333;}#mermaid-svg-HuuoVyU3BNNqoAjd .cluster-label span{color:#333;}#mermaid-svg-HuuoVyU3BNNqoAjd .label text,#mermaid-svg-HuuoVyU3BNNqoAjd span{fill:#333;color:#333;}#mermaid-svg-HuuoVyU3BNNqoAjd .node rect,#mermaid-svg-HuuoVyU3BNNqoAjd .node circle,#mermaid-svg-HuuoVyU3BNNqoAjd .node ellipse,#mermaid-svg-HuuoVyU3BNNqoAjd .node polygon,#mermaid-svg-HuuoVyU3BNNqoAjd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HuuoVyU3BNNqoAjd .node .label{text-align:center;}#mermaid-svg-HuuoVyU3BNNqoAjd .node.clickable{cursor:pointer;}#mermaid-svg-HuuoVyU3BNNqoAjd .arrowheadPath{fill:#333333;}#mermaid-svg-HuuoVyU3BNNqoAjd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HuuoVyU3BNNqoAjd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HuuoVyU3BNNqoAjd .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-HuuoVyU3BNNqoAjd .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-HuuoVyU3BNNqoAjd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HuuoVyU3BNNqoAjd .cluster text{fill:#333;}#mermaid-svg-HuuoVyU3BNNqoAjd .cluster span{color:#333;}#mermaid-svg-HuuoVyU3BNNqoAjd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HuuoVyU3BNNqoAjd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否 是 输入点集 点集是否为空? 创建点索引对 返回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
标签:

【Grasshopper】【Python】点集排序:带索引的Z字形排序算法由讯客互联创业栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【Grasshopper】【Python】点集排序:带索引的Z字形排序算法