import math from ezdxf.enums import TextEntityAlignment import core from drawer.BaseDrawer import BaseDrawer, VentGraphDrawer from entity.primitives import Window, AirDuct class DuctDrawer(BaseDrawer): WIDTH_MULTIPLIER = 1.5 HEIGHT_MULTIPLIER = 1 / 6 def __init__(self, obj, msp, style): super().__init__(obj, msp, style) if self.style == 1: self.obj.color = (0, 255, 255) self.line_height = 50 if self.style == 0: self.line_height = 0 self.duct_drawers = { 0: self.draw_duct_style_0, 1: self.draw_duct_style_1, } def draw_duct_style_0(self, duct_type): """ 绘制风管路径(支持聚合线和分散线) :param duct_type: 绘制类型,可选 'agg'(聚合线)或 'div'(分散线) """ assert isinstance(self.obj, AirDuct) assert duct_type in {'agg', 'div'}, "Invalid duct type. Must be 'agg' or 'div'." # 根据类型选择对应的线段属性 line_attr = 'agg_line' if duct_type == 'agg' else 'div_line' # 遍历路径列表并绘制 for i in range(len(self.obj.path_list)): path = self.obj.path_list[i] start_point, end_point = getattr(path, line_attr) # 获取起点和终点 self.draw_air_duct_list_0(start_point, end_point) # 绘制当前线段 # 如果不是最后一段,绘制连接线 if i + 1 < len(self.obj.path_list): next_start_point = getattr(self.obj.path_list[i + 1], line_attr)[0] connection_line = self.msp.add_line(end_point, next_start_point) connection_line.rgb = self.obj.color # 设置连接线颜色 def draw_duct_style_1(self, duct_type): assert isinstance(self.obj, AirDuct) assert duct_type in {'agg', 'div'}, "Invalid duct type. Must be 'agg' or 'div'." # 根据类型选择对应的线段属性 line_attr = 'agg_line' if duct_type == 'agg' else 'div_line' # 遍历路径列表并绘制 for i in range(len(self.obj.path_list)): path = self.obj.path_list[i] start_point, end_point = getattr(path, line_attr) # 获取起点和终点 self.draw_air_duct_list_2(start_point, end_point) # 绘制当前线段 # 如果不是最后一段,绘制连接线 if i + 1 < len(self.obj.path_list): next_start_point = getattr(self.obj.path_list[i + 1], line_attr)[0] connection_line = self.msp.add_line(end_point, next_start_point, dxfattribs={"layer": f"图层{self.obj.layer_id}", "lineweight": 50}) connection_line.rgb = self.obj.color # 设置连接线颜色 def draw_agg(self): self.duct_drawers[self.style]('agg') def draw_div(self): self.duct_drawers[self.style]('div') def initialize_data(self): pass # d1 a1 b1 # c1|----------c2|F|c3 # d2 center a2 b2 def draw_air_duct_list_0(self, from_, to_): distance = core.distance(from_, to_) ad_len = self.get_draw_air_duct_len() ad_height = self.obj.width * 0.3 ad_width = self.obj.width * 3 # if from_[0] < to_[0]: # route_ = core.calculate_angle_with_x_axis(from_, to_) # else: # route_ = core.calculate_angle_with_x_axis(to_, from_) # route_ = core.calculate_angle_with_x_axis(from_, to_) seg_from = from_ while distance > ad_len: seg_to = core.find_point_on_segment(seg_from, to_, ad_len) center_ = core.find_point_on_line(seg_from, seg_to, 1 / 8) self.draw_single_duct_0(center_, route_, ad_width, ad_height) seg_from = seg_to distance = distance - ad_len self.draw_single_duct_0(seg_from, route_, distance, ad_height) def draw_air_duct_list_2(self, from_, to_): distance = core.distance(from_, to_) ad_len = self.get_draw_air_duct_len() ad_height = self.obj.width * 0.3 ad_width = self.obj.width * 3 route_ = core.calculate_angle_with_x_axis(from_, to_) seg_from = from_ while distance > ad_len: seg_to = core.find_point_on_segment(seg_from, to_, ad_len) self.draw_single_duct_1(seg_from, route_, ad_width, ad_height) seg_from = seg_to distance = distance - ad_len self.draw_single_duct_1(seg_from, route_, distance, ad_height) def draw_line(self, start, end): dxfattribs = {"layer": f"图层{self.obj.layer_id}", "lineweight": self.line_height} line = self.msp.add_line(start, end, dxfattribs=dxfattribs) line.rgb = self.obj.color return line def draw_air_duct(self, center, route): c1 = center[0] - self.obj.width * self.WIDTH_MULTIPLIER, center[1] c2 = center[0] + self.obj.width, center[1] c1 = core.rotate_point_around_another(c1, center, route) c2 = core.rotate_point_around_another(c2, center, route) line = self.msp.add_line(c1, c2, dxfattribs={"layer": f"图层{self.obj.layer_id}"}) line.rgb = self.obj.color d1 = center[0] - self.obj.width * 1.5, center[1] + self.obj.width * 1 / 6 d2 = center[0] - self.obj.width * 1.5, center[1] - self.obj.width * 1 / 6 d1 = core.rotate_point_around_another(d1, center, route) d2 = core.rotate_point_around_another(d2, center, route) line = self.msp.add_line(d1, d2, dxfattribs={"layer": f"图层{self.obj.layer_id}"}) line.rgb = self.obj.color a1 = center[0] + self.obj.width * 1, center[1] + self.obj.width * 1 / 6 a2 = center[0] + self.obj.width * 1, center[1] - self.obj.width * 1 / 6 a1 = core.rotate_point_around_another(a1, center, route) a2 = core.rotate_point_around_another(a2, center, route) line = self.msp.add_line(a1, a2, dxfattribs={"layer": f"图层{self.obj.layer_id}", }) line.rgb = self.obj.color f = center[0] + self.obj.width * 1.25, center[1] f = core.rotate_point_around_another(f, center, route) if route < 0: route = route + math.pi angle = math.degrees(route) dxfattribs = { 'insert': f, 'style': 'msyh', "layer": f"图层{self.obj.layer_id}", } text = self.msp.add_text("F", rotation=angle, dxfattribs=dxfattribs, height=self.obj.width / 6).set_placement(f, align=TextEntityAlignment.MIDDLE_CENTER) text.rgb = self.obj.color b1 = center[0] + self.obj.width * 1.5, center[1] + self.obj.width * 1 / 6 b2 = center[0] + self.obj.width * 1.5, center[1] - self.obj.width * 1 / 6 b1 = core.rotate_point_around_another(b1, center, route) b2 = core.rotate_point_around_another(b2, center, route) line = self.msp.add_line(b1, b2, dxfattribs={"layer": f"图层{self.obj.layer_id}"}) line.rgb = self.obj.color def get_draw_air_duct_len(self): return self.obj.width * 3.5 # a1 a3 # c1|---|c2 # a2 a4 def draw_single_duct_1(self, center, route, ad_len, ad_height): c1 = center c2 = center[0] + ad_len, center[1] a1 = center[0], center[1] + ad_height a2 = center[0], center[1] - ad_height a3 = c2[0], c2[1] + ad_height a4 = c2[0], c2[1] - ad_height c2 = core.rotate_point_around_another(c2, center, route) a1 = core.rotate_point_around_another(a1, center, route) a2 = core.rotate_point_around_another(a2, center, route) a3 = core.rotate_point_around_another(a3, center, route) a4 = core.rotate_point_around_another(a4, center, route) self.draw_line(c1, c2) self.draw_line(a1, a2) self.draw_line(a3, a4) # a1a3 # |F|c1---c2 # a2a4 def draw_single_duct_0(self, center, route, ad_len, ad_height): f_p = center angle = math.degrees(route) if 180 < angle: angle = angle + 180 dxfattribs = { 'insert': f_p, 'style': 'msyh', "layer": f"图层{self.obj.layer_id}", } text = self.msp.add_text("F", rotation=angle, dxfattribs=dxfattribs, height=self.obj.width / 6).set_placement( f_p, align=TextEntityAlignment.MIDDLE_CENTER) text.rgb = self.obj.color c1 = center[0] + 1 / 8 * ad_len, center[1] c2 = center[0] + ad_len, center[1] a1 = center[0] - 1 / 8 * ad_len, center[1] + ad_height a2 = center[0] - 1 / 8 * ad_len, center[1] - ad_height a3 = center[0] + 1 / 8 * ad_len, c2[1] + ad_height a4 = center[0] + 1 / 8 * ad_len, c2[1] - ad_height c1 = core.rotate_point_around_another(c1, center, route) c2 = core.rotate_point_around_another(c2, center, route) a1 = core.rotate_point_around_another(a1, center, route) a2 = core.rotate_point_around_another(a2, center, route) a3 = core.rotate_point_around_another(a3, center, route) a4 = core.rotate_point_around_another(a4, center, route) self.draw_line(c1, c2) self.draw_line(a1, a2) self.draw_line(a3, a4)