四叉树在空间结构建模中的应用
文章目录
- 1、概述
- 2、复杂屋面建模及模型修改思路
- 3、四叉树算法的应用
- 4、修改示例
1、概述
在具有复杂空间造型的屋盖结构设计中,结构建模的工作量通常比较大。结构专业需要根据建筑屋面造型,布置结构杆件,施加荷载,计算分析,确定杆件截面,经过不断调整直至满足设计要求。在整个设计过程中,调整杆件布置的需求来源于2个方面,首先是结构自身的需求,调整杆件的布置以达到最合理的受力体系,另一方面是建筑的需求,特别是在方案阶段,屋面造型的调整导致结构构件需要调整到新的建筑造型位置。结构分析软件的建模功能一般比较弱,调整构件的空间位置是比较困难的,特别是对于屋盖面积大,造型复杂的项目,建模调整的工作量会占结构设计工作量的很大比重。
为减少结构模型修改的工作量,一个方案是在犀牛等建模软件中,布置结构构件,然后导入结构分析软件,赋予杆件截面,施加荷载,但这样只是解决了杆件空间定位问题,赋予杆件截面,施加荷载的工作量仍然很大,在结构反复修改的过程中,要做到建筑建模软件和结构分析软件的高效率联动,目前还是比较困难的。
笔者在多个项目的实践过程中,摸索出一个结合犀牛建模软件、在结构分析软件SAP2000,ETABS中屋面结构建模调整的相对方便、高效的方法,供结构设计中参考。
2、复杂屋面建模及模型修改思路
在犀牛软件中,如下图所示,可以将平面的杆件投影到空间屋面上,形成构件布置的网格,导入结构分析软件中。
在SAP2000结构分析软件中,上面的投影过程,我们也可以直接利用SAP2000 OAPI进行操作。SAP2000 OAPI(Application Programming Interface)是其用于二次开发的核心接口,允许用户通过外部程序(如 Python、C#、VBA、MATLAB 等)自动化控制 SAP2000,实现建模、分析、设计、结果提取及报告生成等任务。
犀牛中的曲面可以转换为由三角形构成的网格,可以编程读取网格信息,将每一个网格作为下面CGArea类的实例保存下来,放到lArea中,这样就得到了整个屋面的空间位置信息。
class CGArea:def __init__(self,name,pti,ptj,ptk):self.name=nameself.pti=ptiself.ptj=ptjself.ptk=ptk
lArea=[]
在SAP2000软件中,我们可以把结构杆件在平面上建模,这通常是比较方便快捷的,直接在平面上赋予杆件截面,并蒙皮加荷载。
接下来就是在sap2000中选中所有的节点,逐个节点遍历lArea数组,判断节点的平面位置位于那一个屋面网格内,找到对应的网格后,计算节点竖向投影到屋面的坐标位置,然后利用SAP2000 OAPI,修改该节点的坐标,这样就能实现复杂屋面的建模工作。
对于屋面修改后,杆件的重新定位,只要重复以上过程,将选中的节点投影到新的屋面即可。
3、四叉树算法的应用
从上面的介绍中,可以看出,对于面积较大的屋面,杆件数量很多,逐个节点遍历lArea数组效率比较低,可以用四叉树算法对这一过程进行优化。
四叉树(Quadtrees)是一种用于二维空间数据分层组织的树状数据结构。其核心思想是将平面区域不断细分,每个节点最多有四个子节点,分别对应四个象限:东北、东南、西北和西南。
四叉树通过递归地将空间分割为四个子区(子树),实现高效的二维空间查询。每个内部节点表示一个大区域,叶节点代表最小单元,如单个点或一个象限。
通过四叉树算法,能够快速确定模型中每一个节点所对应的屋面网格。
四叉树实现的完整python代码如下:
class QuadTreeNode:def __init__(self, x_min, y_min, x_max, y_max, depth=0, max_depth=5, max_areas=10):self.x_min, self.y_min = x_min, y_minself.x_max, self.y_max = x_max, y_maxself.depth = depth self.max_depth = max_depth self.max_areas = max_areas self.areas = [] self.children = [] def insert(self, area):min_x = min(area.pti[0], area.ptj[0], area.ptk[0])min_y = min(area.pti[1], area.ptj[1], area.ptk[1])max_x = max(area.pti[0], area.ptj[0], area.ptk[0])max_y = max(area.pti[1], area.ptj[1], area.ptk[1])if max_x < self.x_min or min_x > self.x_max or max_y < self.y_min or min_y > self.y_max:return Falseif self.children:inserted = Falsefor child in self.children:if child.insert(area):inserted = Trueif inserted:return True # 只要插入到任一子节点即成功self.areas.append(area)if self.depth < self.max_depth and len(self.areas) > self.max_areas:self._split()return Truedef _split(self):mid_x = (self.x_min + self.x_max) / 2mid_y = (self.y_min + self.y_max) / 2self.children = [QuadTreeNode(self.x_min, self.y_min, mid_x, mid_y, self.depth+1, self.max_depth, self.max_areas),QuadTreeNode(mid_x, self.y_min, self.x_max, mid_y, self.depth+1, self.max_depth, self.max_areas),QuadTreeNode(self.x_min, mid_y, mid_x, self.y_max, self.depth+1, self.max_depth, self.max_areas),QuadTreeNode(mid_x, mid_y, self.x_max, self.y_max, self.depth+1, self.max_depth, self.max_areas),]for area in self.areas:for child in self.children:child.insert(area)self.areas = [] # 分裂后当前节点不再存储面def query(self, point):x, y = point[0], point[1]# 若点不在当前节点区域内,返回空列表if not (self.x_min <= x <= self.x_max and self.y_min <= y <= self.y_max):return []# 收集当前节点的所有面candidates = self.areas.copy()# 递归查询子节点for child in self.children:candidates.extend(child.query(point))return candidatesclass AreaFinder:def __init__(self, areas):if not areas:raise ValueError("至少需要一个三角形面")min_x = min(min(area.pti[0], area.ptj[0], area.ptk[0]) for area in areas)min_y = min(min(area.pti[1], area.ptj[1], area.ptk[1]) for area in areas)max_x = max(max(area.pti[0], area.ptj[0], area.ptk[0]) for area in areas)max_y = max(max(area.pti[1], area.ptj[1], area.ptk[1]) for area in areas)padding = max(max_x - min_x, max_y - min_y) * 0.1min_x -= paddingmin_y -= paddingmax_x += paddingmax_y += paddingself.quadtree = QuadTreeNode(min_x, min_y, max_x, max_y)for area in areas:self.quadtree.insert(area)def find_containing_area(self, point):candidates = self.quadtree.query(point)for area in candidates:if area.is_point_inside_projection(point):return areareturn None
4、修改示例
图1为建筑屋面上下表皮调整后,原屋面结构杆件与新屋面的位置关系,从图中可以看出,若在结构软件中手工调整,其难度和工作量都很大。将模型转到犀牛软件中调整,工作量同样也很大。应用本文的方法,可以快速进行调整,效果如图2所示,结构杆件和新的屋面位置严格重合,这使得结构工程师可以从繁重的建模工作中得以解脱,大大提高工作效率。
图1. 屋面结构调整前
图2. 屋面结构调整后