编程助解传统问题──绘制烟囱弯脖平面图

软件世界

  一、又是一年“秋”来到──铁皮匠们的困惑

  中秋节又到了,阵阵凉意袭来,在北方生活过的朋友可能知道,不少地方为了御寒要开始准备生炉子了,相应地就要准备烟囱了。

  我姥爷是远近闻名的铁皮匠,手艺好得没得说,白铁皮到了他手里,一般的锅盆没有做不出的。前阵,他给我出了道不大不小的难题:烟囱弯脖处的展开图怎样画呢(图1)?我想这问题太简单了嘛!用笔在纸上涂了半天,将纸做的模型剪下三接五拼,可当真正将两截纸筒接在一起时就出了问题,费了九牛二虎之力,结果还是没搞出来。姥爷说:“我们老铁皮匠,100人当中,也就能有一个将它画出来。”听姥爷这么说,我就决定用编程来绘制准确的烟囱弯脖平面图,来解开老一代铁皮匠的困惑。

  二、抛开现象看本质──分析问题

  解决这个其实就是解决一个数学问题。我们先再次审视一下这个弯脖!烟囱弯脖实质上是两个圆筒交叉形成的(如图1左图所示),两个交叉的烟囱一样粗细,又垂直相交,交叉面是个椭圆,且同两个烟囱壁都呈45度的角。我们可找两截粉笔或其他的东西磨掉一部分看一下,下面来看看问题的难点。

  要将烟囱展开放在一个平面上, 怎样将这个平面图做出呢?

  两节烟囱是一样的,所以我们只要研究一个就可以了,在这一个烟囱中,由于两半是相同的,我们只要研究其中的一半就行了。我们的工作事实上就是将阴影部分展开成一个平面。我们就以这部分为例加以说明。

  要展开阴影部分,BC边是容易算的,展开后是一条直线,长度为πr,难点就在于要展开椭圆的部分,即CA边。它一定不是一条直线,或者说是一条我们并不确定的曲线,怎样展开呢?

  图2上的E、K两点就是两个特殊点,展开后的E'、K'两个点的位置如图很容易确定。我们现在就是要找出更多的CA边上的点,按一定的规律将它展开,并在展开图上确定它的位置。

  具体的规律可以看如下的一个例子:

  在弧CA上任取一点W,对应的OW和OM的夹角为θ, 角WOC对应的弧长就为θr,这样就得到了展开图上的CW的长度。

  接下来要求展开图上K'W的长度,而这个长度也就是KW(图2),问题转化为求NM的长度,这就比较简单了。它的长度等于:r-rCosθ。这样,这个问题就从理论上解决了。我们只要尽量多地取θ的不同值,通过描点的方法,平面图也就有了。

  三、展现科技魅力──编程解题

  绘制原理

  做平面图实质上是通过描点的方式来完成的一个近似图。每一个θ值要求前面说的两个值。取点数越多,图就越精确。在这里我们取314个点来做出这个图形,加上开始的0位置,一共315个点。这么多的点,最好通过数组来完成,因为一个点要用两个值,所以可通过二维数组来完成。定义二维数组a(1,314),其中a(0,0)-a(0,314)表示在CB'边上取得的点到C的距离,而a(1,0)-a(1,314)表示圆弧上的某点到椭圆截面的距离。而我们做图,可以充分利用上述两数组中的数据。

  界面设计

  界面比较简单,建立一个标准EXE工程,在窗体中放入一个按钮,一个标签,两个文本框和一个图片框。按钮用来控制代码执行,标签起到说明的作用,文本框一个,用来调整半径r的大小,另一个则用来输出对应的各数值对。图片框用来输出图像。(如图3)

  源代码及解释

  Dim a(1, 314) As Double

  Dim r As Long '半径

  Private Sub CmdCalcu_Click() '计算并画图

  Dim i, j As Integer

  Picture1.Cls

  r = Val(TxtNumber.Text) '输入半径值(毫米为单位)

  If r = 0 Then r = 100

  For i = 0 To 314 '计算到K点的距离

  a(0, i) = i * r / 100

  Next i

  For i = 0 To 314 '计算截面到底边的距离

  a(1, i) = r - Cos(i / 100) * r

  Next i

  TxtListnum.Text = “”

  '在文本框中输入几组值

  For i = 0 To 314 Step 10

  TxtListnum.Text = TxtListnum.Text + “第” + Str(Int(i / 10) + 1) + “组:” + Str(a(0, i)) + “\” + Str(a(1, i)) + vbCr + vbLf

  Next i

  For i = 0 To 314 Step 1 '绘制左半边图片框

  Picture1.Line (10 + a(0, i), 10)-(10 + a(0, i), 10 + a(1, i)), vbBlue

  Next i

  For i = 314 To 0 Step -1 '绘制右半边图片框

  Picture1.Line (10 + 314 * r / 100 + a(0, i), 10)-(10 + 314 * r / 100 + a(0, i), 10 + a(1, 314 - i)), vbRed

  Next i

  End Sub

  (以上程序在VB6.0中文企业版、Win2000下调试通过)

  四、处处留心皆学问──生活中的素材

  一个困惑了多少铁皮匠的问题通过电脑就这样轻松而准确地解决了。其实这里面也没有什么高深的知识,只是把具体问题抽象为数学问题来解决。我姥爷那代人没赶上电脑,我们有了电脑,对生活中的问题稍加注意,再加上勤动手,就可以让电脑为我们服务了!留心生活,到处都是编程的素材。