为什么这个简单的物理自由落体代码不起作用

时间:2015-01-25 19:53:35

标签: c#

我创建了一些代码来模拟真空中物体的自由落体。当时间步长设置为1000毫秒时,它可以完美地工作,没有任何问题。当我将时间步长设置为低于1000毫秒时,它会偏离实际值,远远低于正常值。在1000毫秒下降1000米这需要大约14秒,这是正确的值。在100ms时间步长只需5秒。在10毫秒,它只需要2.2秒。

有人可以告诉我我做错了什么吗?我以为我设置了时间步长计算,以便能够处理更小的步骤。

谢谢

        Body testbody = new Body();
        testbody.pos = new Vector(0, 1000);
        testbody.velocity = new Vector(0, 0);
        Bodytrack(testbody);

        static void Bodytrack(Body body)
        {
            watch.Start();
            int timestep = 1000;
            while (body.pos.Y > 0)
            {
                body.pos = body.pos + (body.velocity * (timestep / 1000.0));
                if (body.pos.Y <= 0) { break; }
                Thread.Sleep(timestep);
                CalculateAcceleration(body);
                Console.Clear();
                Console.WriteLine(body.velocity.Y);
                Console.WriteLine(body.pos.Y);
                Console.WriteLine(watch.Elapsed.TotalSeconds);
            }
            watch.Stop();
        }



        public static void CalculateAcceleration(Body body)
        {
            body.acceleration = new Vector(0, -9.80665);
            body.velocity = Vector.Add(body.acceleration, body.velocity); 
        }

2 个答案:

答案 0 :(得分:2)

这一行是你的问题:

body.acceleration = new Vector(0, -9.80665);

每次循环时,都会将加速度设置为-9.8(这是1000ms的加速度),而不是经过的时间加速度。

您需要考虑通过的时间量。如果已经过了500ms,那么加速度应该只是-9.80665 / 2.

您需要将方法更改为:

public static void CalculateAcceleration(Body body, int timestep)
{
   body.acceleration = new Vector(0, -9.80665 * (timestep/1000));
   body.velocity = Vector.Add(body.acceleration, body.velocity); 
}

答案 1 :(得分:0)

如果我正确地记住了我的数学(并设法使用降价将其写下来)......

这个想法是水平位置不受任何影响,重力只会影响垂直位置。因此,我们可以轻松地计算对象的水平位置(假设没有碰撞)。

X(t) = Vx * t

这意味着当你以每秒10米的速度水平扔东西时,它会在10秒后行进100米。

水平定位的公式更先进一些。它包含两部分,第一部分是没有重力的运动,第二部分是重力作用的反作用力。

Y(t) = Vy * t - (g * t^2)/2其中g是重力(通常是9.82)。

Vy * t如果重力不会使其下降,则向上运动。 (g * t^2)/2是引力的增加。

被删除的对象在任何方向都没有初始力,因此{Vx = 0Vy = 0}您可以随时使用{{1}轻松获取当前位置}。 (我们也知道它会直接下降,所以你不必计算任何水平位置。)你已经知道pos(t) = -(g * t^2)/2的速度。

您不能像代码那样信任时间片。首先,Thread.Sleep并不准确。如果计算自上次更新以来经过的时间,最好在计算中使用它。