C#:对象超出目标

发布于 2024-10-21 15:07:42 字数 2106 浏览 8 评论 0原文

我无法诊断以下问题。

有 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();
        }
    }
}

I am having trouble diagnosing the following issue.

There are 2 objects, a ring and a target. The ring represents a ship and the target represents the destination. When the user clicks anywhere in the window, the target is placed where you click and the ship then moves to that location. The problem that I am having is the further the ship has to move, the more velocity that ship will achieve, thus overshooting its target. The further the ship has to move translates to a slower deceleration. I am not sure where this is happening. I have provided the code below:

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();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不可一世的女人 2024-10-28 15:07:42

这并不像看上去那么简单。困难之处在于你必须让你的船以 0 速度到达正确的位置。

如果您想正确执行并且不害怕数学,请实现 PID 控制器。这是解决此类问题的标准方法。它在工业中经常用于自动驾驶仪等。

但是还有一种更简单的方法!

如果您已经直接朝目标行驶,您可以计算如果您现在开始减速,您最终会到达哪里。
假设您的减速度是恒定的:

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

endPos 是您现在开始制动时最终到达的位置。您可以将其与您的目标进行比较,看看您当前是否超出或低于目标。

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

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

这里的减速度是您需要给予船舶停在您想要的位置的“推力”它到。

我希望这对您有所帮助,如果您有任何不明白的地方,或者想要解释我是如何得出上述公式的,请告诉我。

This is less trivial than it seems. What makes it hard is you have to make your ship end up at the right position, with 0 velocity.

If you want to do it right and aren't afraid of maths, implement a PID controller. This is the standard way to solve these kinds of problems. It is uesd often in the industry for things such as autopilots.

However there is an easier way!

If you are already travelling straight towards your target, you can calulate where you will end up if you started decelerating now.
Assuming your deceleration is constant:

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

endPos is where you would end up if you started braking now. You can compare it to your target to see if you are currently overshooting or undershooting.

If you know that you need to brake, you can calculate exactly how much you need to brake to arrive at your target by rearranging the above formula:

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

The deceleration here is the 'thrust' that you need to give your ship to stop where you want it to.

I hope this helps, please tell me if you don't understand anything, or want an explanation to how I came up with the above formulas.

不知所踪 2024-10-28 15:07:42

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

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

This is a common issue with physics simulations. What you'll want to do is, for every update, check the path from the last known position to the current position. If there's any geometry in the way, you know that you should have collided.

At that point you can choose how to react. Many physics libraries like Farseer will actually move the object back to the point of collision and then let the reaction (bounce, spin, etc.) happen from there

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文