浅论换热器管板管孔排布算法
- 格式:doc
- 大小:148.50 KB
- 文档页数:9
1 / 9
浅论换热器圆形管板布管算法
基于AutoCAD的VBA的算法例程
内容摘要:本文介绍了换热器设计中圆形管板布管过程的相关算法及基于AutoCAD的VBA的一个算法例程。
关键词:AutoCAD VBA 布管 算法 例程
我从事换热器的设计工作。在对换热器进行设计的时候需要对换热管进行布管。而换热管的布置对换热器的性能计算和强度计算均有关系,其在性能试算中需要进行多次反复,如果手工布管不仅耗费大量的时间也影响工作效率。因为工作需要,我对换热管布管的算法进行了思考和设计。为了方便下一步的绘制工作,算法的实现基于AutoCAD的VBA。这样,布管的成果可以直接应用到图纸中去。
现今的计算机工业设计软件已经有了许多用于布管的程序,并且大型的设计系统也包括有布管的部分。但对于只需要布管运算的低端应用,在AutoCAD上的扩展程序并不多见。现有的扩展程序在绘制图形时都会自动生成相应的线形图层。这不仅使得图层繁复,打印容易出错,而且每个人都有自己的图层使用习惯,程序生成的图形可能会与使用者的原图纸图样显得格格不入。基于这样现状,我决定按照自己的算法写一个例程。这个例程不创建新的图层,而是由使用者来选择已有的图层进行图样的绘制。
程序所使用的术语
中心孔位置:最接近布管圆圆心的管孔的横向位置,分为跨中和居中两种。
中心管纵向间距:由垂直直径分开的管孔间距,如果为0,则表示垂直直径上可以布管。
中心管横向间距:由水平直径分开的管孔间距,如果为0,则表示水平直径上可以布管。
目标平台的选择
对于直接在AutoCAD上进行的二次开发,其所使用的语言有AutoLisp和VBA之分。AutoLisp是AutoDesk公司自家开发的语言,比VBA更接近AutoCAD系统,更能发挥AutoCAD的功能。但VBA也有自己的优势,它的数据种类多于AutoLisp,而且VBA语言对对话框的设计能力比AutoLisp强大。
综合考虑之后,我决定使用VBA来编写算法例程。
算法思路
对于布管的算法,程序需要进行的运算主要是确定管孔的位置和对于布管区域的限制。我的想法是由简入繁,先按照管孔大小和管间距,以及布管特征在布管圆所在的外接正方形内进行布管。然后再依照布管圆对所有的管孔进行裁减。这样的算法在思路上比较清晰。将管孔是否存在的检验运算和它的位置运算分开进行,会使得计算更加明了,运算的数量也将会少些。 2 / 9
在绘制图样时,由使用者来选择各种线形所在的图层,而不是自动生成所需的线形图层更能符合使用者的图层使用习惯,方便使用者管理图层和使用已有的图纸模版。这样可以加强程序的亲和力和易用性,并且就代码而言,实现起来并不复杂。
算法例程代码及解释
根据布管所需的数据确定窗口界面的布局和样式(窗口见附图[1])。在窗口中添加了“线条设置”一栏,通过两个下拉列表框让使用者选择绘图时所要用到的中心线和轮廓线的图层。这个设置可以使得图形符合使用者的图层使用习惯。
在窗口载入的时候需要进行初始化设置,具体代码如下:
Private Sub UserForm_Initialize()
' 相应的初始化
排布方式.Clear
排布方式.AddItem "三角排列", 0
排布方式.AddItem "正方排列", 1
排布方式.ListIndex = 0
中心孔位置.Clear
中心孔位置.AddItem "跨中", 0
中心孔位置.AddItem "居中", 1
中心孔位置.ListIndex = 0
Dim i As Integer
中心线图层.Clear
轮廓线图层.Clear
For i = 0 To yers.Count - 1
中心线图层.AddItem yers.Item(i).Name, i
轮廓线图层.AddItem yers.Item(i).Name, i
Next
End Sub
通过对yers属性的操作,可以得到当前AutoCAD图形的图层设置信息,并将此信息(图层的名字)添加到下拉列表框中。当改变下拉列表框的选择后,就可以使用如下代码对图层进行选择:
ThisDrawing.ActiveLayer = yers.Item(中心线图层.ListIndex)
当使用者填入所有信息后,就可以单击“开始绘图”按钮进行图样的绘制,当绘制完成后,布管的数量将会在窗口界面左下的信息框里显示出来(未布管前显示:待排管)。
在整个布管及绘制图样的流程中,主要有这四个主要步骤:
1.)进行数据检查
对用户输入的数据进行合法性和合理性的检查,比如输入的数据均需为正,且管间距需大于管孔直径、布管圆直径需大于管孔直径等等。如果数据不正确或不合 3 / 9
理将提醒用户进行改进。
此处也可以根据相关标准对数据进行检查,比如根据GB151,管间距推荐为管孔直径的1.25倍等。
2.)定义相应数据结构
Type FPoint
X as double
Y as double
End type
Dim number As Integer ’记录管孔数量的变量
Dim 纵向最大管数 As Integer
Dim 横向最大管数 As Integer
If 排布方式.ListIndex = 0 Then
'三角排布
纵向最大管数 = CInt((CDbl(布管圆直径.Text) / 2 – CDbl(_
中心管纵向间距.Text) / 2) / ((CDbl(管间距.Text)) / 2_
)* Tan(Pi / 3))
Else
'正方排布
纵向最大管数 = CInt((CDbl(布管圆直径.Text) / 2 - CDbl(_
中心管纵向间距.Text) / 2) / CDbl(管间距.Text))
End If
横向最大管数 = CInt((CDbl(布管圆直径.Text) / 2 - CDbl(中心管横向间距.Text) / 2) / CDbl(管间距.Text))
ReDim 管孔位置(0 To 纵向最大管数 - 1, 0 To 横向最大管数 - 1) As FPoint
ReDim 管孔存在(0 To 纵向最大管数 - 1, 0 To 横向最大管数 - 1) As Boolean
首先定义的是点的数据类型(FPoint),然后根据排管方式确定最大的横、纵向排管数量,因为算法例程为横、纵对称,故只计算四分之一的区域即可。然后根据最大的排管数量定义两个二维数组(“管孔位置”和“管孔存在”)。管孔位置数组记录管孔相对于布管圆中心的偏移。管孔存在记录这个管孔是否需要被裁减。
3.)布管
'排管流程
If 排布方式.ListIndex = 0 And 中心孔位置.ListIndex = 0 Then
'三角排列 跨中
For i = 0 To 纵向最大管数 - 1
For j = 0 To 横向最大管数 - 1
If i Mod 2 = 0 Then
'奇数排 4 / 9
管孔位置(i, j).x = CDbl(中心管横向间距.Text) / 2 + j * CDbl(_
管间距.Text) + CDbl(管间距.Text) / 2
Else
'偶数排
管孔位置(i, j).x = CDbl(中心管横向间距.Text) / 2 + j * CDbl(_
管间距.Text)
End If
管孔位置(i, j).y = CDbl(中心管纵向间距.Text) / 2 + i * (CDbl(_
管间距.Text) / 2) * Tan(Pi / 3)
Next
Next
ElseIf 排布方式.ListIndex = 0 And 中心孔位置.ListIndex = 1 Then
'三角排列 居中
For i = 0 To 纵向最大管数 - 1
For j = 0 To 横向最大管数 - 1
If i Mod 2 = 0 Then
'奇数排
管孔位置(i, j).x = CDbl(中心管横向间距.Text) / 2 + j * CDbl(_
管间距.Text)
Else
'偶数排
管孔位置(i, j).x = CDbl(中心管横向间距.Text) / 2 + j * CDbl(_
管间距.Text) + CDbl(管间距.Text) / 2
End If
管孔位置(i, j).y = CDbl(中心管纵向间距.Text) / 2 + i * (CDbl(_
管间距.Text) / 2) * Tan(Pi / 3)
Next
Next
ElseIf 排布方式.ListIndex = 1 And 中心孔位置.ListIndex = 0 Then
'正方排列 跨中
For i = 0 To 纵向最大管数 - 1
For j = 0 To 横向最大管数 - 1
管孔位置(i, j).x = CDbl(中心管横向间距.Text) / 2 + j * CDbl(_
管间距.Text) + CDbl(管间距.Text) / 2
管孔位置(i, j).y = CDbl(中心管纵向间距.Text) / 2 + i * CDbl(_
管间距.Text)
Next
Next
ElseIf 排布方式.ListIndex = 1 And 中心孔位置.ListIndex = 1 Then
'正方排列 居中
For i = 0 To 纵向最大管数 - 1