C#:对象超过目标

时间:2011-03-14 01:47:18

标签: c# vector xna physics velocity

我无法诊断出以下问题。

有2个物体,一个戒指和一个目标。环表示船舶,目标表示目的地。当用户单击窗口中的任意位置时,目标将放置在您单击的位置,然后该船将移动到该位置。我遇到的问题是船舶必须移动的距离越远,船舶将达到的速度越快,从而超越其目标。船舶必须进一步移动转换为较慢的减速度。我不确定这是怎么回事。我提供了以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace ArtificialDumb
{
    class PhysicsObject
    {
        public Vector2 Position;
        public Vector2 OldPosition;

        public float Mass;

        public Vector2 Acceleration;

        public float Drag = 0.01f;

        public PhysicsObject(float x, float y)
        {
            Position = OldPosition = new Vector2(x, y);
        }

        public PhysicsObject(Vector2 pos)
        {
            Position = OldPosition = pos;
        }

        public virtual void Update()
        {
            Vector2 velocity = Position - OldPosition;

            velocity *= (1 - Drag);

            OldPosition = Position;
            Position += velocity;

            Position += Acceleration;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace ArtificialDumb
{
    class Ship : PhysicsObject
    {
        public float MaxThrust;

        public Vector2 Target;

        public Ship(Vector2 pos)
            : base(pos)
        {
            MaxThrust = 50f;
            Mass = 100;
        }

        public override void Update()
        {
            Vector2 diff = Target - Position;
            Vector2 Velocity = (Position - OldPosition);


            // Dark Magic. Do Not Touch.
            // This is the equation for projectile velocity. -ASR
            // Edited for correct float value -ASR
            // people keep touching! - AgH
            Vector2 thrust = diff - (Velocity * Velocity.Length() * 0.75f);

            thrust.Normalize();
            // todo: Account for when we don't need to use maximum thrusters
            thrust *= MaxThrust;

            Acceleration = thrust / Mass;
            base.Update();
        }
    }
}

2 个答案:

答案 0 :(得分:2)

这不像看起来那么简单。难以置信的是,你必须让你的船以0速度结束在正确的位置。

如果你想做得好并且不怕数学,那就实施PID controller。这是解决这类问题的标准方法。对于像自动驾驶仪这样的事情,它在业内经常出现。

然而,有一种更简单的方法!

如果您已经直接朝目标前进,那么如果您现在开始减速,您可以计算最终结果。 假设你的减速度是恒定的:

endPos = Position + (Velocity * Velocity) / (2 * deceleration);
如果你现在开始制动,那么你最终会到达endPos。您可以将其与目标进行比较,以查看您当前是否超调或下冲。

如果您知道需要刹车,可以通过重新排列上述公式来精确计算制动到达目标的准确程度:

deceleration  = (Velocity * Velocity) / (2 * (endPos - Position));

这里的减速是你需要让你的船停在你想要的地方的“推力”。

我希望这会有所帮助,如果您不理解任何内容,请告诉我,或者想要解释我如何提出上述公式。

答案 1 :(得分:0)

这是物理模拟的常见问题。您要做的是,对于每次更新,检查从上一个已知位置到当前位置的路径。如果路上有任何几何形状,你知道你应该碰撞。

此时您可以选择如何反应。像Farseer这样的许多物理库实际上会将物体移回碰撞点,然后让反应(反弹,旋转等)从那里发生