えいまぼJEブログ

Minecraft Java Editionに関していろいろ書きます

TNTの座標計算 #3 - 単位TNT推力

前回: TNTの座標計算 #2 - 複数の装薬 - えいまぼJEブログ

環境はMinecraft Java Editionです。

単位TNT推力の式

単位TNT推力1とは、装薬TNT1つで弾頭TNTが飛ぶ距離のことです。 装薬がN個あるとき、弾頭TNTの飛ぶ距離は「『単位TNT推力』×N」となります。飛ぶ距離が比例の関係にあるので、とても使いやすい考え方です。

さて、単位TNT推力は、以下の式で表されます。

\\\
u _ x = 50 \times V _ x \times (1 - 0.98 ^ T) \\\
u _ y = 50 \times V _ y \times (1 - 0.98 ^ T) \\\
u _ z = 50 \times V _ z \times (1 - 0.98 ^ T)

x, y, z軸ですべて共通です。

ただし、諸定数は図1に基づき、以下のように定義します。

図1

  •  X : 装薬と弾頭との距離のx成分
  •  Y : 装薬と弾頭との距離のy成分
  •  Z : 装薬と弾頭との距離のz成分
  •  R : 装薬と弾頭との距離  \displaystyle R = \sqrt{X ^ 2 + Y ^ 2 + Z ^ 2}
  •  \displaystyle T = 弾頭着火\rm{gt} - 装薬着火\rm{gt} + 1
  •  \displaystyle V _ {x} = \left(1 - \frac{R}{8}\right) \frac{X}{R}
  •  \displaystyle V _ {y} = \left(1 - \frac{R}{8}\right) \frac{Y}{R}
  •  \displaystyle V _ {z} = \left(1 - \frac{R}{8}\right) \frac{Z}{R}

使い方

例えばx方向の単位TNT推力が10の装薬がほしいなら、 u _ x = 10 となるように  V _ x T を調節します。

x方向の単位TNT推力  u _ x を10としたいときの、装薬と弾頭の間の距離を求めてみます。 ここでは、弾頭爆発時間までの時間を20gt ( T = 20)とします。

まず、 V _ x を以下のように求めます。

\\\
\begin{align}
V _ x &= \displaystyle \frac{u _ x}{50 \times (1 - 0.98 ^ T)} \\\
 &= \displaystyle \frac{10}{50 \times (1 - 0.98 ^ {20})} \\\
 &= 0.6017...
\end{align}

 V _ x から装薬と弾頭をどのくらいの距離にするかを求めます。 \displaystyle V _ {x} = \left(1 - \frac{R}{8}\right) \frac{X}{R} を使います。 ここでは計算の簡略化のため、 X = R とします。Minecraftでは、装薬の爆発y, z座標が弾頭のy, z座標と一致している状況になります。座標指定型TNTキャノンでは理想の状態です。

\\\
\begin{align}
V _ {x} &= \left(1 - \frac{R}{8}\right) \frac{X}{R} \\\
 &= \displaystyle 1 - \frac{X}{8}
\end{align}

式を変形します。

\\\
\begin{align}
X &= 8 \times \left(1 - V _ x\right) \\\
 &= 8 \times \left(1 - 0.6017...\right) \\\
 &= 3.1864...
\end{align}

これで、 T = 20 でx方向の単位TNT推力  u _ x を10としたいときの装薬と弾頭の距離を求めることができました。3ブロックと少し離すと良いことがわかりました。

導出

単なる式変形ですが、導出過程を載せます。

x軸

x座標は式1で表されます(前回の記事より)。

 \displaystyle x = x _ 0 + 50 \times (N V _ x + v _ {0x}) \times (1 - 0.98 ^ T) \tag{1}

これを展開し、 u _ x を当てはめます(式2)。


\begin{align}
\displaystyle x &= x _ 0 + 50 \times N V _ x \times (1 - 0.98 ^ T) + 50 \times v _ {0x} \times (1 - 0.98 ^ T) \\\
\displaystyle  &= x _ 0 + N u _ x + 50 \times v _ {0x} \times (1 - 0.98 ^ T) \tag{2}
\end{align}

定数項を  C _ x = x _ 0 + 50 \times v _ {0x} \times (1 - 0.98 ^ T) としてまとめます(式3)。

 \displaystyle x = N u _ x + C _ x \tag{3}

y軸

y軸もx軸と同様に導出します。

y座標は式4で表されます(前回の記事より)。

 \displaystyle y = y _ 0 + 50 \times (N V _ y + v _ {0y} + 1.96) \times (1 - 0.98 ^ T) - 2 T \tag{4}

これを展開し、 u _ y を当てはめます(式5)。


\begin{align}
\displaystyle x &= y _ 0 + 50 \times N V _ y \times (1 - 0.98 ^ T) + 50 \times (v _ {0y} + 1.96) \times (1 - 0.98 ^ T) - 2 T \\\
\displaystyle  &= y _ 0 + N u _ y + 50 \times (v _ {0y} + 1.96) \times (1 - 0.98 ^ T) - 2 T \tag{5}
\end{align}

定数項を  C _ y = y _ 0 + 50 \times (v _ {0y} + 1.96) \times (1 - 0.98 ^ T) - 2 T としてまとめます(式6)。

 \displaystyle x = N u _ y + C _ y \tag{6}

これで、装薬  N 個で弾頭がどのくらい飛ぶかが単位TNT推力を使って示されました。

z軸

z軸はx軸と全く同じなので省略します。

y軸特有の注意

y軸はx, z軸と違い、注意点があります。 それは、切片(オフセット)の扱いです。

弾頭を真上に打ち上げるタイプのTNTキャノンを考えます。この場合、以下の条件が成り立つので、  x = N u _ x と考えることができます ( C _ x = 0)。

  •  x _ 0 = 0 (相対座標なので)
  •  v _ {0x} = 0 (水平方向の速度はないので)

一方でy座標は絶対座標であり( y _ 0 \neq 0)、 50 \times (v _ {0y} + 1.96) \times (1 - 0.98 ^ T) - 2 T をゼロにするのは難しいので、一般的には  C _ y 0 にできないことがわかります。 一応  v _ {0y} を調整することで  C _ y = 0 にすることも可能です。しかし、そうするよりも切片を最初から考慮していたほうが実用的かと思います。y座標は絶対座標なので。

別の注意点としては、 T を切り替えて平面軸の単位TNT推力を変更する方式2は切り替えによって  C _ y が大きく変わる点があります。 楽に作るのであれば  T を切り替えずに固定としたほうが良さそうです。 実際、y軸入力対応のTNTキャノン3では  T を切り替えませんでした( C _ y を固定として扱った)。

理論上の限界

単位TNT推力の上限値は40.068 (≒ 50×1×(1 - 0.98 ^ 80))です。 なお、この値はコマンド以外ではほぼ実現不可能です。 装薬の爆発座標と弾頭座標が限りなく近い(ただし一致ではない)状況でなければ上限値は出せません4

検証環境

Minecraft Java Edition 1.17.1-1.18.1


前回: TNTの座標計算 #2 - 複数の装薬 - えいまぼJEブログ