えいまぼJEブログ

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

TNTの座標計算 #1 - 式と導出

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

環境はMinecraft Java Editionです。

結論

1つの装薬が図1のような位置で爆発したとき、弾頭の速度・位置は以下の式で表されます。

図1

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

ただし、

  •  X : 装薬と弾頭との距離のx成分
  •  Y : 装薬と弾頭との距離のy成分
  •  Z : 装薬と弾頭との距離のz成分
  •  \displaystyle R = \sqrt{X ^ 2 + Y ^ 2 + Z ^ 2}
  •  \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}
  •  v _ {0x} : 装薬の爆発を受ける前に持っていた速度のx成分
  •  v _ {0y} : 装薬の爆発を受ける前に持っていた速度のy成分
  •  v _ {0z} : 装薬の爆発を受ける前に持っていた速度のz成分
  •  v _ x : 速度のx成分
  •  v _ y : 速度のy成分
  •  v _ z : 速度のz成分
  •  x _ 0 : x座標の初期座標 (装薬の爆発を受ける点)
  •  y _ 0 : y座標の初期座標 (装薬の爆発を受ける点)
  •  z _ 0 : z座標の初期座標 (装薬の爆発を受ける点)
  •  x : x座標
  •  y : y座標
  •  z : z座標
  •  \displaystyle T = 弾頭着火\rm{gt} - 装薬着火\rm{gt} + 1

です1

※z座標・速度のz成分は図に描画していません(できません)。

導出

Minecraft内での処理

Minecraft内のTNTの座標・速度演算は図2のようになっています。

図2. Minecraft内での座標・速度演算
①はy軸専用の処理です。x, z軸は①がありません。

なお、この図はMinecraft Java Edition 1.17.1のソースコードに基づいて描かれました。ソースコードを見たい場合は逆コンパイルするか、Technical Minecraft Wikiaを覗いてみてください。Technical Minecraft Wikiaのコードは1.17.1と変わりませんでした。ですので、これより古いバージョンでも使える数式だと思われます。 統合版でも適用できるかはわかりません2

速度のx成分

まずは一番簡単な速度のx成分を導出します。図3は図2から速度のx成分の計算に必要な処理のみを抜粋したものです。

図3. 速度のx成分の処理

図3から、漸化式が導けます(式1)。

 \displaystyle v _ {n+1} = v _ n \times 0.98 \tag{1}

式1を解くと、式2のようになります。

 \displaystyle v _ {n} = v _ 0 \times 0.98 ^ n \tag{2}

式2の  v _ n v _ x に、 v _ 0 V _ x + v _ {0x} に、 n T に置き直して完成です(式3)。

 \displaystyle v _ {x} = (V _ x + v _ {0x}) \times 0.98 ^ T \tag{3}

速度のy成分

次は速度のy成分を導出します。図4は図2から速度のy成分の計算に必要な処理のみを抜粋したものです。

図4. 速度のy成分の処理

図4から、以下の漸化式が導けます(式4)。

 \displaystyle v _ {n+1} = 0.98 (v _ n - 0.04) \tag{4}

式4を特性方程式などを使って解くと、式5のようになります。

 \displaystyle v _ {n} = (v _ 0 + 1.96) 0.98 ^ n - 1.96 \tag{5}

式5の  v _ n v _ y に、 v _ 0 V _ y + v _ {0y} に、 n T に置き直して完成です(式6)。

 \displaystyle v _ {y} = (V _ y + v _ {0y} + 1.96) 0.98 ^ T - 1.96 \tag{6}

速度のz成分

速度のz成分はxと全く同じです。 x ( X) を  z ( Z) に置き換えるだけで成立します。

x座標

次は座標xを導出します。図5は図2からx座標の計算に必要な処理のみを抜粋し、式を導出しやすいよう処理の順番を変えたものです。

図5. x座標の処理

図2の時点では座標の更新(②)が最後ではないので、そのまま式を導出できません。そこで、③をループの一番最初に持っていき、その分を④で補います。

導出は、

  1. 始めは④がなかったものとして計算
  2. 最後に④を考慮

という方針です。

では、図5の②から漸化式を導きます。式7のようになります。

 \displaystyle x _ {n+1} =  x _ n + v _ {n + 1} \tag{7}

式7の  v _ {n + 1} は、意味合いとしては式2と等価ではありません。しかし、形は変わらないのでそのまま適用します(この意味はy座標を求めるときにわかります)。よって、式2を式7に適用した漸化式は式8のようになります。

 \displaystyle x _ {n+1} =  x _ n + v _ 0 \times 0.98 ^ {n + 1} \tag{8}

式8は式9のように変形できます。

 \displaystyle x _ n =  x _ 0 + \sum _ {k = 0} ^ {n - 1} v _ 0 \times 0.98 ^ {k + 1} \tag{9}

式9を等比数列の和の公式を使って解くと式10のようになります。

 \displaystyle x _ n =  x _ 0 + 50 \times 0.98 \times v _ 0  \times (1 - 0.98 ^ n) \tag{10}

ここで、④を展開します。式10で  \displaystyle v _ 0 = v _ 0 / 0.98 と置き直すと式11のようになります。

 \displaystyle x _ n =  x _ 0 + 50 \times v _ 0  \times (1 - 0.98 ^ n) \tag{11}

ここで式11の  x _ n x に、 v _ 0 V _ x + v _ {0x} に、 n T に置き直して完成です(式12)。

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

y座標

最後は座標yを導出します。図6は式を導出しやすいよう図2の処理の順番を変えたものです。

図6. y座標の処理

ここからの導出はx座標と同様です。

図2の時点では座標の更新(②)が最後ではないので、そのまま式を導出できません。 そのため、③をループの一番最初に持っていき、その分を④で補います。

導出は、

  1. 始めは④がなかったものとして計算
  2. 最後に④を考慮

という方針です。

では、図6の②から漸化式を導きます。式13のようになります。

 \displaystyle y _ {n+1} =  y _ n + v _ {n + 1} \tag{13}

式13の  v _ {n + 1} は、意味合いとしては式5と等価ではありません。ここはx座標と違ってこのまま式5を適用できません。よって、ここで"図6の③・①における"  v _ n を求めます。漸化式は式14になります。

 \displaystyle v _ {n+1} =  0.98 v _ n - 0.04 \tag{14}

式14を解くと、式15になります。

 \displaystyle v _ {n} = (v _ 0 + 2) 0.98 ^ n - 2 \tag{15}

ここで式15を式13に適用します。漸化式は式16のようになります。

 \displaystyle y _ {n+1} =  y _ n + (v _ 0 + 2) 0.98 ^ {n + 1} - 2 \tag{16}

式16は式17のように変形できます。

 \displaystyle y _ n =  y _ 0 + \sum _ {k = 0} ^ {n - 1} (v _ 0 + 2) \times 0.98 ^ {k + 1} - \sum _ {k = 0} ^ {n - 1} 2 \tag{17}

式17を等比数列の和の公式などを使って解くと式18のようになります。

 \displaystyle y _ n =  y _ 0 + 50 \times 0.98 \times (v _ 0 + 2)  \times (1 - 0.98 ^ n) - 2 n \tag{18}

ここで、④を展開します。式18で  \displaystyle v _ 0 = v _ 0 / 0.98 と置き直すと式19のようになります。

 \displaystyle y _ n =  y _ 0 + 50 \times (v _ 0 + 1.96)  \times (1 - 0.98 ^ n) - 2 n \tag{19}

ここで式19の  y _ n y に、 v _ 0 V _ y + v _ {0y} に、 n T に置き直して完成です(式20)。

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

z座標

z座標はxと全く同じです。 x ( X) を  z ( Z) に置き換えるだけで成立します。

弾頭の爆発座標

この記事で導出した座標は弾頭TNT本体の座標になります。弾頭の爆発座標は y に 0.06125 (= 0.98 / 16) を加算した値になります。Carpet Modの/log explosions briefで出る値は爆発座標なので、取り違えにご注意ください(1敗)。

前々回のブログ記事について

前々回のブログは1gtあとの速度を初速度としています。 そのため、式の形が今回とは違います。 「なんかよくわからんけど2%増しにすると値が合う」と書いたのは1gtあとの速度を初速度としたためだと思われます。

検証環境

Minecraft Java Edition 1.17.1-1.18.1


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


  1. gt:ゲームティック。一般的には1gt = 0.05秒として差し支えありません。
  2. x, z軸は適用できる可能性があります。統合版の報告で示された係数は同じでした(0.96035 ^ 0.5 ≒ 0.98)。