在达到最终目的地之前,以任何给定值(例如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没有响应。有人能指出我正确的方向吗?
答案 0 :(得分:1)
好像你在混合速度(速度)和加速度。速度是相对于给定时间范围的位置变化。加速度是相对于给定时间范围的速度变化。对于恒定加速度,位置和速度的变化如下:
v1 = v0 + a * t
x1 = x0 + v0 * t + 1/2 * a * t^2
v0
,v1
和x0
,x1
分别是时间范围开头和结尾的速度和位置,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
结构。这使得很多事情变得更容易。您可以添加两个向量,而不必分别关注每个组件。有一些方法可以获得矢量的长度,等等。