これは非常に単純な学部物理の問題です。x 方向と y 方向のニュートンの法則から始めます。
初期条件付き:
ここで、Q は発射体の初速度、シータは銃が右を向いている場合に水平線から反時計回りに測定した角度です。
したがって、それぞれを 1 回ずつ統合すると、次のようになります。
初期条件の適用:
もう一度積分すると、次のようになります。
初期条件を再度適用します。
置換を行うと、銃が爆発した瞬間からの発射体の (u, v) 位置に必要な最終的な方程式が得られます。
座標系の原点を銃口の出口に置くと、2 つの初期変位はゼロになります。
これで、発射体の (u, v) 位置に関する 2 つの方程式が得られました。発射体の初速度と、水平線から右を向いて測定した銃の角度を差し込むことができます。
時間ゼロから開始し、時間の増分を選択して、好きなだけ長い時間間隔でループします。時間の現在の値をこれらの方程式に代入し、結果を評価し、時間を増やして、繰り返します。
水平線から反時計回りに 45 度の角度で銃を向け、毎秒 1000 インチで発射体を発射するとします。時間を進めて、発射体が放物線状の経路で右上に移動し、頂点に到達してから地平線に戻り始めるのを見ることができます。最終的に、y 変位はゼロに戻り、崖の端から撃ったかのように、負の領域に入り続けます。
発射体が地面に衝突するまでにどれくらいの距離を移動したかを知りたい場合は、高さがゼロ以下になったときにタイム ループを停止します。
これがあなたのためのJava実装です:
package physics;
/**
* CannonSimulator simulates shooting a projectile. Users are responsible for making
* sure that all constants use consistent units (e.g. meters for length, seconds for
* time, kg for mass, etc.)
* @author Michael
* @since 6/14/12 9:47 PM
* @link http://stackoverflow.com/questions/10935060/2d-projectile-tracing-path-clarification/11043389#11043389
*/
public class CannonSimulator {
private double m;
private double g;
private double q;
private double theta;
public static void main(String[] args) {
double m = ((args.length > 0) ? Double.valueOf(args[0]) : 1.0); // default mass is 1 kg
double g = ((args.length > 1) ? Double.valueOf(args[1]) : 9.8); // default gravity is 9.8 m/sec^2
double q = ((args.length > 2) ? Double.valueOf(args[2]) : 100.0); // default velocity is 100 m/sec
double theta = ((args.length > 3 ? Double.valueOf(args[3]) : Math.PI/4.0)); // default angle is 45 degrees
CannonSimulator simulator = new CannonSimulator(m, g, q, theta);
double t = 0.0;
double dt = 0.001; // time increment of 0.1 seconds
while (simulator.v(t) >= 0.0) {
System.out.println(String.format("time: %10.3f u: %10.3f v: %10.3f", t, simulator.u(t), simulator.v(t)));
t += dt;
}
}
public CannonSimulator(double m, double g, double q, double theta) {
if (m <= 0.0) throw new IllegalArgumentException("mass must be greater than zero");
if (g <= 0.0) throw new IllegalArgumentException("gravity must be greater than zero");
if (q <= 0.0) throw new IllegalArgumentException("velocity must be greater than zero");
this.m = m;
this.g = g;
this.q = q;
this.theta = theta;
}
public double v(double time) {
return time*(q*Math.sin(theta) - g*time/m);
}
public double u(double time) {
return time*q*Math.cos(theta);
}
}
それがこの問題を解決する方法です。