从 A 减速到 B 减速(数学)XNA

Moving from A to B deceleration (Maths) XNA

在到达最终目的地之前以任何给定值(例如 accelerationDropOff = 1.5f)的速度减速的最佳方法是什么?

public bool MoveFromCurrentToPosition(float x, float y, float velocity, float acceleration, float deltaTime)
    {
        float startX = positionX, startY = positionY;
        float endX = x, endY = y;
        float deltaX = endX - startX;
        float deltaY = endY - startY;
        float speed = velocity;
        float elapsed = 0.01f;

        // On starting movement
        float distance = (float)Math.Sqrt(Math.Pow(deltaX, 2) + Math.Pow(deltaY, 2));
        float directionX = deltaX / distance;
        float directionY = deltaY / distance;
        isMoving = true;

        // On update
        if (isMoving == true)
        {
            positionX += directionX * speed * elapsed;
            positionY += directionY * speed * elapsed;

            if (currentAcceleration == 0)
            {
                currentAcceleration = acceleration;
            }
            else if (currentAcceleration >= maxAcceleration) // <- Don't accelerate anymore
            {
                speed *= currentAcceleration;
                positionX += (directionX * speed) * deltaTime; positionY += (directionY * speed) * deltaTime;
                bounds.X = (int)positionX; bounds.Y = (int)positionY;
            }
            else
            {
                currentAcceleration += acceleration;
                speed *= currentAcceleration;
                positionX += (directionX * speed) * deltaTime; positionY += (directionY * speed) * deltaTime;
                bounds.X = (int)positionX; bounds.Y = (int)positionY;
            }

            float a = x, o = y;
            double angle = Math.Atan2(o, a);
            angle = angle * 180 / Math.PI;
            movementDirection = (float)(180 - angle);


            // Decelerate before reaching the end point



            if (Math.Sqrt(Math.Pow(positionX - startX, 2) + Math.Pow(positionY - startY, 2)) >= distance)
            {
                positionX = endX;
                positionY = endY;
                isMoving = false;

                return true;
            } 
        }

        return false;
    }

我已经在这个问题上停留了一两个小时,Math.exe 没有响应。谁能给我指出正确的方向?

您似乎混淆了速度(速度)和加速度。速度是相对于给定时间范围的位置变化。加速度是相对于给定时间范围的速度变化。对于恒定加速度,位置和速度变化如下:

v1 = v0 + a * t
x1 = x0 + v0 * t + 1/2 * a * t^2

v0v1x0x1分别是时间帧开始和结束的速度和位置,a是加速度,t是时间帧长度。如果您假设在时间范围内持续加速,这就是精确的公式。通常,您会发现类似下面的近似值,它们会引入一些积分错误:

v1 = v0 + a * t
x1 = x0 + v1 * t

我建议使用准确的公式。

据我了解你的问题,你想要找到一个加速度,使得以初始速度 v0 移动的物体在行进 d 个长度单位后停止。

这为您提供了以下等式:

0 = v0 + a * t                    //target velocity of 0
d =  0 + v0 * t + 1/2 * a * t^2   //travel distance of d

解决方法是:

a = -1/2 * v0^2 / d

此动作所需时间为:

t = 2 * d / v0

所以在减速运动开始时计算一次加速度,然后用上面的公式更新当前位置和速度。

对您的代码的一些额外提示:

如果要对变量 x 求平方,请使用 x * x 而不是 Math.pow(x, 2)。它更易于阅读并且具有更好的性能。

如果您已经在使用 XNA,请使用它的 Vector2 结构。这使很多事情变得容易得多。您可以只添加两个向量,而不需要分别关心每个组件。有获取向量长度的方法,等等。