这是一个非常简单的本科物理问题。您从 x 和 y 方向的牛顿定律开始:


初始条件:




其中 Q 是弹丸的初始速度,而 theta 是如果枪指向右侧,则从地平线逆时针测量的角度。
因此,如果您将每一项整合一次,您将获得:


应用初始条件:


第二次积分给出:


再次应用初始条件:

从枪响起,进行替换就可以得到您想要的射弹 (u, v) 位置的最终方程:


如果把坐标系的原点放在枪口出口处,那么两个初始位移为零。
现在你有两个方程来表示弹丸的 (u, v) 位置。您可以插入弹丸的初始速度和枪的角度,从地平线测量为零,指向右侧。
您只需从零开始,选择时间增量,然后循环任意长的时间间隔。您将时间的当前值插入这些方程式,评估结果,增加时间,然后重复。
让我们想象一下,您将枪从地平线逆时针倾斜 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);
}
}
这就是解决这个问题的方法。