2025年9月2日 星期二

理論與實際

理論與實際


曾慶潭 Ching-Tang Tseng
ilikeforth@gmail.com
Hamilton, New Zealand
2 September 2025


子彈跟砲彈都不是飛彈,發射出去以後的飛行軌跡無法修正,它們的理論彈道是固定的,如果不考慮環境因素的影響,也不考慮彈藥質地的統計性差異,落點就是確定值。排除這些因素,根據理論公式設計砲彈射擊程式,是件趣味事情。

我從網上的社群網頁收集到這一張簡圖,它就在顯示砲彈彈道的理論公式,我拿它來設計程式,實際上的有用應用,應該還要添加以程式修正發射角度的能力。


我是職業軍人,只是專長比較特殊,從中正理工學院核子工程系畢業後,必須前往最基層的正規野戰部隊服役,我前往的部隊番號是陸軍第 57 師,這個師傳統上對軍官的要求比較嚴格。我駐防馬祖時,幹到 57 師連長後才考進中山科學研究院,看過軍史記錄,確認 1941 年 57 師打過長沙會戰,1974 年,連上還有經歷過長沙會戰的老士官班長。 57 師是輕裝師,新報到的軍官一律拔掉軍階,在幹訓班重訓單兵、伍、班、排之槍砲操練三個月,成績記入軍籍表。


以砲操為例,解釋理論彈道公式的用途,才能結合理論與實際來設計程式。

砲操的射擊口令是這樣喊出來的:

第一砲注意
12 點鐘方向
目標正前方機槍陣地
俯角 30 度
榴彈一發
裝藥兩包


戰場的口令都很簡潔,我們從口令的內容來解釋理論彈道公式中那些參數比較有用。

一門砲有裝填彈藥的士兵、操作瞄準具的士兵、射手。

聽到 12 點鐘方向口令時,砲口會轉置到正前方的大約位置。
聽到目標正前方機槍陣地口令時,瞄準手會進行精確的直線對準瞄準。
聽到俯角 30 度口令時,瞄準手會將發射砲口調整出俯角 30 度的角度。
聽到榴彈一發口令時,彈藥兵與裝填手會將一發榴彈砲彈塞進砲管發射座。
聽到裝藥兩包口令時,彈藥兵會塞進兩包炸藥包,關上砲栓。
聽到放的口令時,砲彈就發射出去了。轟的一聲,震耳欲聾。

現在回頭看彈道貼圖,砲彈射擊時,完成砲口直線瞄準後,確實只剩二維內的事項必須考慮,而且只須調整砲口的發射俯角單一個參數。

那一種砲彈、裝藥幾包,決定了砲彈的發射初速,這項決定由喊口令的砲長負責,砲兵只管操作。換句話說,每次發射砲彈,最後,只有一個參數需要調整,也就是發射俯角。

從實務的觀點來看貼圖,實際上彈道的軌跡,也就是 y 與 x 的關係,在沒有繪圖功能時,不太有用。我只令 x 等於最高高度之值來敷衍過去。

這樣理解砲操,就可以開始設計程式了。我設計的數學計算系統很簡明,彈道公式完全可以直接搬入程式。為了表示式能更清晰的顯示,幾個用到的三角函數數值,直接在輸入數據後就立刻執行,產生結果,所以我不吝於變數用量,直接宣告出 14 個變數的名稱來設計程式。

砲彈不是發射出去就算了,砲長直接觀察落點,或前進觀測官會回報落點與目標差了多少角度與多少公尺。砲長在發射下一發砲彈時就得修正涉及參數。修正的主值,除了直線瞄準外,仍然是發射俯角需要改為幾度。

於是,我再根據公式,增加設計了一個 adj 指令,這個指令可憑需要增加或減少落點的距離直接換算出新的發射俯角,提供的答案仍是砲口應該升或降的新角度。應該增加的公尺數用正值輸入,必須減少的公尺數用負值輸入。操作方式只用兩個指令,執行 main 指令時,只根據結果印出彈道相關之數據供砲長參考。需要修正發射俯角時,執行 adj 指令便可。程式附帶簡單的操作,列示如下:


\ shell.f

\ degree : 發射俯角(度度量)
\ z : 弳度量
\ T : 飛行時間 ( sec )
\ R : 炸點距離 ( m )
\ H : 最高高度 ( m )
\ y : 彈道軌跡 ( m )
\ x : 水平距離 ( m )
\ u : 砲彈初速 ( 250 m/sec )
\ g : 重力加速度 ( 9.8 m/sec^2 )
\ a : 調整距離 ( +/-m )

14 reals degree z u g T H R y x sinz sin2z cosz tanz a

: InputData basic
10 let { degree = 30.0 e 0 }
20 let { z = degree * f(pi) / 180.0 e 0 }
30 let { u = 250.0 e 0 } 
40 let { g = 9.8 e 0 }
50 let { sinz = sin ( z ) }
60 let { sin2z = sin ( f2.0e0 * z ) }
70 let { cosz = cos ( z ) }
80 let { tanz = tan ( z ) }
90 end ;

: main basic
10 run InputData
20 let { T = ( f2.0e0 * u * sinz ) / g }
30 let { H = ( (  u * u ) * ( sinz * sinz ) ) /  ( f2.0e0 * g ) }
40 let { R = ( u * u ) * sin2z / g }
50 let { x = H }
60 let { y = x * tanz - ( g * x * x ) / (  f2.0e0 * u * u * cosz * cosz ) }
70 run cr ." 發射俯角 = " degree f.  ." 度 "
       cr ." 飛行時間 = " T f. ." 秒 "
       cr ." 最高高度 = " H f. ." 公尺 "
       cr ." 炸點距離 = " R f. ." 公尺 "
       cr ." 砲彈初速 = " u f. ." 公尺/秒 "   
\ 70 print { z , T , H , R , u }
80 end ;

: adj basic
10 run cr ." 輸入修正距離為幾公尺? " cr
20 InputR a
30 let { R = R + a }
40 let { z = asin ( ( R * g ) / ( u * u ) ) / f2.0e0 }
50 let { degree = z * 180.0 e 0 / f(pi) }
60 run cr ." 修正射角成為 " degree f. ." 度 " cr
70 end ;

hing@ctt:~$ ./l

AMDX86 ciforth 5.3.0 
fload shell.f
g : ISN'T UNIQUE                                                
A : ISN'T UNIQUE                                                
 OK
main

發射俯角 = 30.0度 
飛行時間 = 25.510204081秒 
最高高度 = 797.19387755公尺 
炸點距離 = 5523.1211976公尺 
砲彈初速 = 250.0公尺/秒  OK
adj

輸入修正距離為幾公尺? 

? +230.0 e 0

修正射角成為 32.21704191  度 
 OK
adj

輸入修正距離為幾公尺? 

? -45.0 e 0

修正射角成為 31.756360366  度 
 OK

沒有留言: