-1

2D游戏中的弹丸追踪路径问题:

假设:

我们做了一个简化的假设,即重力是恒定的并且没有风或阻力。弹丸的运动由以下方程给出:

x = x0 + v0t cos(theta)

y = y0 + v0t sin(theta) + .5 gt^2

其中 (x0, y0) 是初始位置,v0 是初始速度(仅幅度),theta 是排放角,g 是重力加速度。求解 v0t 的第一个方程并代入第二个方程,我们得到方程 [1]:

y = y0 + (x-x0) tan(theta) + .5 (g/v0^2) (x-x0)^2 / cos(theta)^2

校准:

校准是根据实际弹丸确定 g 值的过程。为此,我们发射一个随机射弹并捕获:

  1. 起点 (x0, y0)
  2. 目标向量 (v0, theta)
  3. 曲线上的一个随机点 (x1, y1)

将这些值代入方程 [1] 并求解 g,我们得到:

g = (v0^2) * {[2 cos(theta)^2 (y1-y0) / (x1-x0)^2] - [sin(2theta) / (x1-x0)]}

应用:

现在我们有了 g,我们可以将其代回方程 [1],现在可以使用该方程从任何起点和初始速度跟踪射弹的路径。(这是我不明白的部分)

g=5.89

(x0,y0) 起始位置 = 0,0

初始速度 = 1-100

放电角度 = 0-360

有人可以解释一下,如果重力加速度为 5.89(在这个游戏中),那么对于 1-100 之间的任何初始速度和 0-360 之间的任何放电角,如何获得抛物线的完整绘制路径,并且开始位置是0,0?

我是一个数学新手,所有这些东西都不是我在别处找到的粗体字,而且我一直在绞尽脑汁。请假设我什么都不知道。

4

3 回答 3

2

您只会错过第一组方程中的时间t 和空间/时间约束,绘制射弹的前 x 秒或直到射弹离开边界框 m。所以伪代码是:

  • t=0;x(0)=某个坐标;y(0)=另一个坐标
  • 环路
  • t=t+1
  • 计算坐标 {X(t=1), Y(t=1)}
  • 在此点与前一个点之间绘制点或线
  • LOOP UNTIL t>time limit OR point {X(t), Y(t)} 在你的边界框之外

我希望这对你的努力有所帮助

于 2012-06-07T15:50:26.037 回答
2

选择v0 = 10theta = 60 degrees我们有

tan(theta) = 1.732
cos(theta) = 0.5

因此等式1显示为 ( x0=0, y0=0,g=5.89给出)

y = 1.732*x - 0.1178*x^2

可以直接绘制(yvs. x):见这里

注意:我更正了-重力的符号。

于 2012-06-07T17:28:17.133 回答
0

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

x方向的力平衡

y方向的力平衡

初始条件:

零时的 x 位移

零时的 x 速度

零时间的 y 位移

零时间的 y 速度

其中 Q 是弹丸的初始速度,而 theta 是如果枪指向右侧,则从地平线逆时针测量的角度。

因此,如果您将每一项整合一次,您将获得:

x-速度与时间

y 速度与时间的关系

应用初始条件:

x-速度常数

y-速度常数

第二次积分给出:

x 位移与时间的关系

y 位移与时间

再次应用初始条件:

x位移初始条件

y 位移初始条件

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

作为时间函数的射弹的 x 位置

弹丸的 y 位置作为时间的函数

如果把坐标系的原点放在枪口出口处,那么两个初始位移为零。

现在你有两个方程来表示弹丸的 (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);
    }
}

这就是解决这个问题的方法。

于 2012-06-15T01:02:55.610 回答