# -*- coding: utf-8 -*-
"""
钢结构格构柱计算与绘图系统 - 自动生成计算书和示意图
"""
import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, Polygon
from datetime import datetime
import os
import re # 添加这一行
class SteelLacedColumnSystem:
"""钢结构格构柱计算与绘图系统"""
def __init__(self, csv_file='channel_sections.csv'):
self.csv_file = csv_file
self.results = {}
self.params = {}
def verify_stability(self, section_name, tie_plate_spacing, plate_size, steel_grade, gap, L, N, fd):
"""钢结构稳定性验算"""
# 保存参数用于绘图
self.params = {
'section_name': section_name,
'tie_plate_spacing': tie_plate_spacing,
'plate_size': plate_size,
'steel_grade': steel_grade,
'gap': gap,
'L': L,
'N': N,
'fd': fd
}
content = []
content.append("# 轴心受压格构柱整体稳定性验算")
content.append("")
try:
df = pd.read_csv(self.csv_file)
numeric_columns = ['A', 'Ix', 'Iy', 'iy', 'x0', 'ix']
for col in numeric_columns:
if col in df.columns:
df[col] = pd.to_numeric(df[col], errors='coerce')
section_data = df[df['model'] == section_name].iloc[0]
except:
error_msg = f"错误: 无法加载截面数据 '{section_name}'"
content.append(error_msg)
return content, False
A_single = section_data['A']
Ix_single = section_data['Ix']
Iy_single = section_data['Iy']
iy_single = section_data['iy']
ix_single = section_data['ix']
y0 = section_data['x0']
fy_dict = {'Q235B': 235, 'Q345B': 345, 'Q390B': 390, 'Q420B': 420}
fy = fy_dict.get(steel_grade, 235)
y0_value = gap - 2 * y0
A_total = 2 * A_single
Ix_total = 2 * (Iy_single + A_single * (y0_value * 0.5) ** 2)
ix_total = math.sqrt(Ix_total / A_total)
iy_total = ix_single
slenderness_ratio_x = L / ix_total
slenderness_ratio_0x = slenderness_ratio_x
slenderness_ratio_1 = (tie_plate_spacing - plate_size[1]) / iy_single
slenderness_ratio_0y = math.sqrt(slenderness_ratio_x ** 2 + slenderness_ratio_1 ** 2)
max_slenderness_ratio = max(slenderness_ratio_0x, slenderness_ratio_0y)
steel_params_b_class = {
'Q235': [0.650, 0.965, 0.300],
'Q345': [0.650, 0.965, 0.300],
'Q390': [0.650, 0.965, 0.300],
'Q420': [0.650, 0.965, 0.300]
}
alpha1, alpha2, alpha3 = steel_params_b_class.get(steel_grade[:-1], steel_params_b_class['Q235'])
lambda_n = max_slenderness_ratio / math.pi * math.sqrt(fy / 206000)
if lambda_n <= 0.215:
phi = 1 - alpha1 * lambda_n ** 2
else:
phi = ((alpha2 + alpha3 * lambda_n + lambda_n ** 2) -
math.sqrt((alpha2 + alpha3 * lambda_n + lambda_n ** 2) ** 2 - 4 * lambda_n ** 2)) / (
2 * lambda_n ** 2)
# 计算稳定承载力
N_capacity = phi * A_total * fd * 0.1
# 输出结果到内容
content.append("## 一、输入参数")
content.append("")
content.append(f"- 槽钢型号: [{section_name}")
content.append(f"- 缀板间距: {tie_plate_spacing*10} mm")
content.append(f"- 缀板尺寸: {plate_size[0]*10}×{plate_size[1]*10}×{plate_size[2]*10} mm")
content.append(f"- 钢材牌号: {steel_grade}, 设计强度:fd= {fd} N/mm²")
content.append(f"- 构件长度: {L/100} m")
content.append(f"- 轴心压力设计值: N={N} kN")
content.append("## 二、截面特性")
content.append(f"- 查阅规范GBT706-2016《热轧型钢》")
content.append(f"- 截面总面积: A=2×{A_single}={A_total} cm²")
content.append(f"- 对x轴回转半径: ix={ix_total:.2f} cm")
content.append(f"- 对y轴回转半径: iy={iy_total:.2f} cm")
content.append("## 三、稳定性计算")
content.append(f"- 对x轴长细比: λx={slenderness_ratio_x:.2f}")
content.append(f"- 单肢长细比: λ1={tie_plate_spacing - plate_size[1]}/{iy_single}={slenderness_ratio_1:.2f}")
content.append(f"- 换算长细比: λ0x = √(λx² + λ1²) = √({slenderness_ratio_x:.2f}² + {slenderness_ratio_1:.2f}²)={slenderness_ratio_0y:.2f}")
content.append(f"- 最大长细比: {max_slenderness_ratio:.2f}")
content.append(f"- 相对长细比 λ_n: λn=λ0x/(π*√(fy/E))={slenderness_ratio_0y:.2f}/π*√(235/2.06×10⁵)={lambda_n:.3f}")
content.append(f"- 稳定系数: φ=1/(2λ²)*[(a2+a3λn+λn²)-√((a2+a3λn+λn²)²-4λn²)]={phi:.4f}")
content.append("## 四、承载力计算")
content.append("")
content.append(f"- 稳定承载力:Ncrd=φAf={phi:.4f}×{A_total}×10²×{fd}={N_capacity:.4f} kN")
content.append(f"- 承载力与设计值比值: ({N}-{N_capacity:.4f})/{N_capacity:.4f}={(abs(N_capacity - N) / N_capacity)*100:.4f}%")
content.append("")
content.append("## 五、验算结果")
content.append("")
if N_capacity >= N:
content.append("✅ 验算结果: 满足承载能力要求")
result = True
else:
content.append("❌ 验算结果: 不满足承载能力要求")
result = False
if abs(N_capacity - N) / N_capacity < 0.05:
content.append("⚠️ 工程设计验算结果:承载力在5%内,可以考虑满足要求")
else:
content.append("⚠️ 工程设计验算结果:承载力不在5%内,考虑不满足要求")
# 保存结果
self.results['stability'] = {
'N_capacity': N_capacity,
'phi': phi,
'slenderness_ratios': {
'x': slenderness_ratio_x,
'y': slenderness_ratio_0y,
'single': slenderness_ratio_1,
'max': max_slenderness_ratio
},
'result': result
}
return content, result
def create_schematic_diagram(self):
"""创建格构柱示意图"""
if not self.params:
return None
fig, ax = plt.subplots(figsize=(12, 10))
ax.set_aspect('equal')
ax.set_xlim(0, 100)
ax.set_ylim(0, 150)
ax.grid(False)
ax.set_axis_off()
# 绘制主视图
up_left_rect = Rectangle((20, 60), 10, 80,
linewidth=2,
edgecolor='black',
facecolor='lightblue')
ax.add_patch(up_left_rect)
up_right_rect = Rectangle((60, 60), 10, 80,
linewidth=2,
edgecolor='black',
facecolor='lightblue')
ax.add_patch(up_right_rect)
down_plate = Rectangle((25, 70), 40, 10,
linewidth=2,
edgecolor='black',
facecolor='none')
ax.add_patch(down_plate)
up_plate = Rectangle((25, 120), 40, 10,
linewidth=2,
edgecolor='black',
facecolor='none')
ax.add_patch(up_plate)
# 绘制俯视图
vertices_1 = np.array([
[20, 20], [20, 45], [30, 45], [30, 42],
[23, 42], [23, 23], [30, 23], [30, 20]
])
left_polygon = Polygon(vertices_1,
closed=True,
linewidth=2,
edgecolor='black',
facecolor='lightblue',
alpha=0.7)
ax.add_patch(left_polygon)
vertices_2 = np.array([
[60, 20], [60, 23], [67, 23], [67, 42],
[60, 42], [60, 45], [70, 45], [70, 20]
])
right_polygon = Polygon(vertices_2,
closed=True,
linewidth=2,
edgecolor='black',
facecolor='lightblue',
alpha=0.7)
ax.add_patch(right_polygon)
Top_down_plate = Rectangle((25, 17), 40, 3,
linewidth=2,
edgecolor='black',
facecolor='none')
ax.add_patch(Top_down_plate)
Top_up_plate = Rectangle((25, 45), 40, 3,
linewidth=2,
edgecolor='black',
facecolor='none')
ax.add_patch(Top_up_plate)
# 添加标注
self._add_annotations(ax)
# 添加标题
# ax.set_title('格构柱结构示意图', fontsize=16, pad=20)
# plt.tight_layout()
# plt.savefig('schematic_diagram.png', dpi=300, bbox_inches='tight', facecolor='white')
# plt.close()
return 'schematic_diagram.png'
def _add_annotations(self, ax):
"""添加标注"""
plate_size = self.params['plate_size']
tie_plate_spacing = self.params['tie_plate_spacing']
section_name = self.params['section_name']
# 绘制标注线
ax.axhline(y=130, xmin=75 / 100, xmax=80 / 100, color='red', linewidth=2, linestyle='-')
ax.axhline(y=120, xmin=75 / 100, xmax=80 / 100, color='red', linewidth=2, linestyle='-')
ax.axhline(y=80, xmin=75 / 100, xmax=80 / 100, color='red', linewidth=2, linestyle='-')
ax.axhline(y=70, xmin=75 / 100, xmax=80 / 100, color='red', linewidth=2, linestyle='-')
ax.axhline(y=75, xmin=5 / 100, xmax=25 / 100, color='red', linewidth=2, linestyle='-')
ax.axhline(y=35, xmin=5 / 100, xmax=25 / 100, color='red', linewidth=2, linestyle='-')
ax.axvline(x=79, ymin=70 / 150, ymax=130 / 150, color='red', linewidth=2, linestyle='-')
# 添加标注文本
ax.text(75, 123, f"{plate_size[1] * 10}", fontsize=12, color='red', ha='center', rotation=90)
ax.text(75, 100, f"{tie_plate_spacing * 10 - plate_size[1] * 10}", fontsize=12, color='red', ha='center',
rotation=90)
ax.text(75, 73, f"{plate_size[1] * 10}", fontsize=12, color='red', ha='center', rotation=90)
ax.text(5, 77, f"-{plate_size[0] * 10}×{plate_size[1] * 10}×{plate_size[2] * 10}", fontsize=12, color='red',
ha='center')
ax.text(5, 37, f"[{section_name}", fontsize=12, color='red', ha='center')
def generate_report(self, section_name, tie_plate_spacing, plate_size,
steel_grade, gap, L, N, fd, filename="钢结构格构柱计算书.docx"):
"""生成完整计算书"""
content = []
content.append("# 钢结构格构柱计算书")
content.append(f"计算时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
content.append("---")
# 稳定性计算
stability_content, stability_result = self.verify_stability(
section_name, tie_plate_spacing, plate_size, steel_grade, gap, L, N, fd
)
content.extend(stability_content)
# 添加示意图
diagram_path = self.create_schematic_diagram()
if diagram_path:
content.append("## 六、结构示意图")
content.append("")
content.append("")
content.append("图1: 格构柱结构示意图")
# 保存到文档
self._create_word_document(content, filename)
return content
def _create_word_document(self, content, filename):
"""创建Word文档"""
try:
from docx import Document
from docx.shared import Inches
doc = Document()
for line in content:
if line.startswith('# '):
doc.add_heading(line[2:], level=0)
elif line.startswith('## '):
doc.add_heading(line[3:], level=1)
elif line.startswith('### '):
doc.add_heading(line[4:], level=2)
elif line.startswith('\)', line)
if match:
image_path = match.group(1)
if os.path.exists(image_path):
doc.add_picture(image_path, width=Inches(4))
doc.add_paragraph("") # 添加空行
else:
doc.add_paragraph(line)
doc.save(filename)
print(f"计算书已保存到 '{filename}'")
except ImportError:
with open(filename.replace('.docx', '.txt'), 'w', encoding='utf-8') as f:
f.write("\n".join(content))
print(f"注意: docx库未安装,计算书已保存为文本文件 '{filename.replace('.docx', '.txt')}'")
def show_schematic(self):
"""显示示意图"""
diagram_path = self.create_schematic_diagram()
if diagram_path and os.path.exists(diagram_path):
img = plt.imread(diagram_path)
plt.figure(figsize=(12, 10))
plt.imshow(img)
plt.axis('off')
plt.title('格构柱结构示意图', fontsize=16)
plt.tight_layout()
plt.show()
def main():
"""主函数"""
calculator = SteelLacedColumnSystem()
# 示例参数
params = {
'section_name': "28b",
'tie_plate_spacing': 83,
'plate_size': [26, 20, 1],
'steel_grade': "Q235B",
'gap': 26,
'L': 600,
'N': 1600,
'fd': 215
}
# 生成计算书
content = calculator.generate_report(**params, filename="钢结构格构柱计算书.docx")
# 显示示意图
calculator.show_schematic()
# 在控制台输出
print("\n".join(content).replace("![图像]", "[图像]"))
if __name__ == "__main__":
main()
帮我看看这个完整的代码,帮我把word输出后的公式改一下格式,表示出如Ncrd的下标crd,并且把输出的计算书格式优化一下