角度 \(\theta\) 、速度 \(v\) で投げ上げた場合を考える。
参考より、空気抵抗をkとして、Unityでの空気抵抗は以下のように計算されているらしいので、
\[v = v * (1 - k*dt); \]
※ 引用元のfはfloatなので省略、\(k\) が空気抵抗(UnityでのDrag)
調査した結果、Unity上で \(dt\) は「Project Settings」「Time」「Fixed Timestep」であった。
物理演算は「Fixed Timestep」ごとに行われ、\(n\) 回かかるものとする。
物理演算は「Fixed Timestep」ごとに行われ、\(n\) 回かかるものとする。
速度は、前の速度から \(1-kdt\) をかけた等比数列なので、速度の一般項 \(v_{xn}\)は
\[v_{xn} = v_{x0} (1 - kdt)^{n} \]
そして位置\(x_1\)を計測したところ、Unity上では\(v_{x0}\)ではなく、\(v_{x1}\)から使われていた。
\(x_0 = 0\) 、
\(x_1 = v_{x1} dt + x_0\)、
\(x_2 = v_{x2} dt + x_1 \ldots\)
よって位置の一般項 \(x_n\) \(\left(n \geq 1\right)\)は、
\(x_0 = 0\) 、
\(x_1 = v_{x1} dt + x_0\)、
\(x_2 = v_{x2} dt + x_1 \ldots\)
よって位置の一般項 \(x_n\) \(\left(n \geq 1\right)\)は、
\begin{eqnarray}
x_n &=& v_{xn} dt + x_{n-1}
\\
&=& v_{xn} dt + v_{xn-1} dt + v_{xn-2} dt \ldots
\\
&=& \left(v_{xn} + v_{xn-1} + v_{xn-2} \ldots + v_{x1} \right) dt
\\
&=& dt\sum_{i=1}^{n}v_{xi}
\\
\end{eqnarray}
初項 \(a = v_1\)、公比 \(r = 1-kdt\) の等比数列の和より、
\begin{eqnarray}
x_n &=& v_{x1}dt\frac{1- {\left(1 - kdt \right)}^n}{1 - (1 - kdt)}
\\
&=& v_{x1}dt\frac{1- {\left(1 - kdt \right)}^n}{1 - 1 + kdt}
\\
&=& v_{x1}dt\frac{1- {\left(1 - kdt \right)}^n}{kdt}
\\
&=& v_{x1}\frac{1- {\left(1 - kdt \right)}^n}{k}
\tag{x}\label{x}
\\
\end{eqnarray}
速度\(v_y\)を計測したところ、Unity上での式は以下のようになっていた。
\[v_{y} = \left(v_y + g * dt \right) * \left(1 - k*dt \right); \]
\(v_x\)と違い、一般項が複雑になるので求めると、
\begin{eqnarray}
v_{y2} &=& \left(v_{y1} + gdt \right)\left(1 - kdt \right)
\\
&=& v_{y1}\left(1 - kdt \right) + gdt \left(1 - kdt \right)
\\
&=& \left(v_{y0} + gdt \right)\left(1 - kdt \right) \left(1 - kdt \right) + gdt \left(1 - kdt \right)
\\
&=& \left(v_{y0} + gdt \right)\left(1 - kdt \right)^2 + gdt \left(1 - kdt \right)
\\
&=& v_{y0}\left(1 - kdt \right)^2 + gdt\left(1 - kdt \right)^2 + gdt \left(1 - kdt \right)
\\
&=& v_{y0}\left(1 - kdt \right)^2 + gdt\left( \left(1 - kdt \right)^2 + \left(1 - kdt \right) + \ldots \right)
\\
&=& v_{y0}\left(1 - kdt \right)^2 + gdt\sum_{i=1}^{2} \left(1 - kdt \right)^i
\\
\end{eqnarray}
\(\sum\)の部分は初項 \(a = 1-kdt\)、公比 \(r = 1-kdt\) の等比数列の和より、
\begin{eqnarray}
v_{y2} &=& v_{y0}\left(1 - kdt \right)^2
+ gdt\left(1-kdt\right) \frac{1-\left(1-kdt\right)^2}{1-\left(1-kdt\right)}
\\
&=& v_{y0}\left(1 - kdt \right)^2
+ gdt\left(1-kdt\right) \frac{1-\left(1-kdt\right)^2}{1-1+kdt}
\\
&=& v_{y0}\left(1 - kdt \right)^2
+ gdt\left(1-kdt\right) \frac{1-\left(1-kdt\right)^2}{kdt}
\\
&=& v_{y0}\left(1 - kdt \right)^2
+ g\left(1-kdt\right) \frac{1-\left(1-kdt\right)^2}{k}
\\
&=& v_{y0}\left(1 - kdt \right)^2
+ \frac{g\left(1-kdt\right)}{k}
- \frac{g\left(1-kdt\right)\left(1-kdt\right)^2}{k}
\\
&=& \left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)^2
+ \frac{g\left(1-kdt\right)}{k}
\\
\end{eqnarray}
よって速度の一般項 \(v_{yn}\) は、
\[v_{yn} = \left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)^n
+ \frac{g\left(1-kdt\right)}{k} \]
位置の一般項\(y_n\) \(\left(n \geq 1\right)\)も、
\(x_n\)と同様に \(\displaystyle dt\sum_{i=1}^{n}v_i\) なので、
\begin{eqnarray}
y_n &=& dt\sum_{i=1}^{n}v_{yi}
\\
&=& dt\sum_{i=1}^{n} \left(
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)^n
+ \frac{g\left(1-kdt\right)}{k}
\right)
\\
&=& dt\left(
\sum_{i=1}^{n}\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)^n
+ \sum_{i=1}^{n}\frac{g\left(1-kdt\right)}{k}
\right)
\\
\end{eqnarray}
初項 \(a = \left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)\)、公比 \(r = 1-kdt\) の等比数列の和より、
\begin{eqnarray}
y_n &=& dt\left(
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)
\frac{1-\left(1-kdt\right)^n}{1- \left(1-kdt\right)}
+ \frac{ng\left(1 - kdt\right)}{k}
\right)
\\
y_n &=& dt\left(
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)
\frac{1-\left(1-kdt\right)^n}{kdt}
+ \frac{ng\left(1 - kdt\right)}{k}
\right)
\\
y_n &=&
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)
\frac{1-\left(1-kdt\right)^n}{k}
+ \frac{ngdt\left(1 - kdt\right)}{k}
\\
\end{eqnarray}
ここから距離を求めたいので、\(y_0 \neq 0 \) から、 \(y = 0 \) となる\(x \) を求める。
※Unityで確認したところ、\(1 - kdt = 0 \)の場合は空気抵抗が釣り合ってしまい、ボールが動かなかったので、\(1 - kdt \neq 0 \)とする
※Unityで確認したところ、\(1 - kdt = 0 \)の場合は空気抵抗が釣り合ってしまい、ボールが動かなかったので、\(1 - kdt \neq 0 \)とする
\begin{eqnarray}
0 &=&
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right) \left(1 - kdt \right)
\frac{1-\left(1-kdt\right)^n}{k}
+ \frac{ngdt\left(1 - kdt\right)}{k}
+ y_0
\\
0 &=&
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{1-\left(1-kdt\right)^n}{k}
+ \frac{ngdt}{k}
+ \frac{y_0}{1 - kdt}
\\
\end{eqnarray}
\eqref{x}より、\( \frac{x_n}{v_{x1}} = \frac{1-\left(1-kdt\right)^n}{k} \) なので、
\begin{eqnarray}
0 &=&
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{x_n}{v_{x1}}
+ \frac{ngdt}{k}
+ \frac{y_0}{1 - kdt}
\\
\end{eqnarray}
\eqref{x}より、
\begin{eqnarray}
x_n &=& v_{x1}\frac{1- {\left(1 - kdt \right)}^n}{k}
\\
\frac{kx_n}{v_{x1}} &=& 1- \left(1 - kdt \right)^n
\\
\frac{kx_n}{v_{x1}} - 1 &=& - \left(1 - kdt \right)^n
\\
1 - \frac{kx_n}{v_{x1}} &=& \left(1 - kdt \right)^n
\\
\log_{\left(1 - kdt \right)}\left(1 - \frac{kx_n}{v_{x1}}\right) &=& n
\\
n &=& \log_{\left(1 - kdt \right)}\left(1 - \frac{kx_n}{v_{x1}}\right)
\\
\end{eqnarray}
よって、
\begin{eqnarray}
0 &=&
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{x_n}{v_{x1}}
+ \frac{gdt}{k} \log_{\left(1 - kdt \right)}\left(1 - \frac{kx_n}{v_{x1}} \right)
+ \frac{y_0}{1 - kdt}
\\
\end{eqnarray}
\(v_{x1} = v_{x0}(1 - kdt) \) より、
\begin{eqnarray}
0 &=&
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{x_n}{v_{x0}(1 - kdt)}
+ \frac{gdt}{k} \log_{\left(1 - kdt \right)}\left(1 - \frac{kx_n}{v_{x0}(1 - kdt)}\right)
+ \frac{y_0}{1 - kdt}
\\
0 &=&
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{kx_n}{gdtv_{x0}(1 - kdt)}
+ \log_{\left(1 - kdt \right)}\left(1 - \frac{kx_n}{v_{x0}(1 - kdt)}\right)
+ \frac{ky_0}{gdt\left(1 - kdt\right)}
\\
\left(1-kdt \right)^0 &=&
\left(1-kdt \right)^{\left(
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{kx_n}{gdtv_{x0}(1 - kdt)}
+ \log_{\left(1 - kdt \right)}\left(1 - \frac{kx_n}{v_{x0}(1 - kdt)}\right)
+ \frac{ky_0}{gdt\left(1 - kdt\right)}
\right)}
\\
1 &=&
\left(1-kdt \right)^{
\log_{\left(1 - kdt \right)}\left(1 - \frac{kx_n}{v_{x0}(1 - kdt)}\right)
}
\left(1-kdt \right)^{\left(
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{kx_n}{gdtv_{x0}(1 - kdt)}
+ \frac{ky_0}{gdt\left(1 - kdt\right)}
\right)}
\\
1 &=&
\left(1 - \frac{kx_n}{v_{x0}(1 - kdt)}\right)
\left(1-kdt \right)^{\left(
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{kx_n}{gdtv_{x0}(1 - kdt)}
+ \frac{ky_0}{gdt\left(1 - kdt\right)}
\right)}
\\
0 &=&
-1 +
\left(1 - \frac{kx_n}{v_{x0}(1 - kdt)}\right)
\left(1-kdt \right)^{\left(
\left(v_{y0} - \frac{g\left(1-kdt\right)}{k} \right)
\frac{kx_n}{gdtv_{x0}(1 - kdt)}
+ \frac{ky_0}{gdt\left(1 - kdt\right)}
\right)}
\\
\end{eqnarray}
これを解けば飛距離\(x_n \) をだせるが、どうやらこの式は解けないようなので、近似値を求めることにした。
既存のライブラリ
で対処したかったが、式のグラフの形が想定されていないのか、\(v_0 \)が400ほどですでに解がだせなかったので、
禁断の自作実装で対処した。
飛距離の最低値は当然0であり、最大値は\eqref{x}の\(n = \infty \)で求められるので、
\begin{eqnarray}
x_{max} &=& v_{x1}\frac{1- {\left(1 - kdt \right)}^\infty}{k}
\\
\end{eqnarray}
\(1-kdt \lt 1 \)より、
\begin{eqnarray}
x_{max} &=& v_{x1}\frac{1- \frac{1}{\infty}}{k}
\\
x_{max} &=& v_{x1}\frac{1- 0}{k}
\\
x_{max} &=& \frac{v_{x1}}{k}
\\
x_{max} &=& \frac{v_{x0}(1 - kdt)}{k}
\\
\end{eqnarray}
飛距離の計算を実現するクラスは以下の通り。
※2025/3/6追記 lowerBoundがupperBound/2だと解が含まれない場合があったので、0に修正
残念ながら飛距離はUnity上でも正確に測れないためか、それとも浮動小数点の計算誤差なのか、値が大きくなると精度の範囲を超えた誤差がでる。(以下の図は精度0.1を指定している)

コメント
コメントを投稿