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

时间:2016-09-10 02:56:28

标签: c# math 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没有响应。有人能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:1)

好像你在混合速度(速度)和加速度。速度是相对于给定时间范围的位置变化。加速度是相对于给定时间范围的速度变化。对于恒定加速度,位置和速度的变化如下:

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结构。这使得很多事情变得更容易。您可以添加两个向量,而不必分别关注每个组件。有一些方法可以获得矢量的长度,等等。