重写使得 Math.atan() 无论方向如何都能工作
Rewriting so that Math.atan() works regardless of orientation
我有一个 2D side-view shooter-thingy 需要重新审视。我目前正在研究瞄准,它部分起作用:枪口速度已知,重力已知,并且到目标的 x,y 距离也是已知的。使用 SE 和维基百科上的各种资源,我想出了以下计算射弹速度起始向量的方法:
public Vector2 calculateAim(Vector2 pos, Unit target) {
// Check if previous calculation can be recycled
if (target.equals(lastTarget))
return lastAim.cpy();
lastTarget = target;
double v = RifleBullet.projectileSpeed; // Muzzle velocity
double g = Settings.gravity.y; // Gravity, positive value
double x = offset.x; // x distance to target. Negative if towards left
double y = offset.y; // y distance to target. Negative if lower
double theta = Math.atan(((v * v) - Math.sqrt((v*v*v*v) - (g*(g*(x*x) + 2*y*(v*v))))) / (g * x));
Vector2 aim = new Vector2(-(float)Math.cos(theta), (float)Math.sin(theta));
aim.nor();
aim.scl((float)RifleBullet.projectileSpeed);
lastAim = aim.cpy();
return aim;
}
以上部分有效:最右边的人会正确瞄准。然而,站在左边的那个人一直在向错误的方向开火。看起来 Y 分量是正确的,但 X 分量完全颠倒了。如果我在计算 theta 之后添加:
if (side.contains("left"))
angleInRadians += Math.PI;
...它们都可以正确开火,但是在很长一段时间内都不可行 运行 因为战场上会有更多的单位,当我到达那个点时它肯定会引起问题。
我认为问题的根源可能是 Math.atan()
函数,因为我没有任何检查来查看三角计算中假设三角形的方向。
我应该如何改进我的方法,以便无论谁left/right/up/down都能正常工作?
Tenfour04 说的很有帮助。您可能想要使用 Math.atan2(y,x)
而不是 Math.atan(y/x)
请注意,您不是自己进行除法,而是将 y 和 x 作为单独的参数给出。这是 atan2 知道 5/2 和 -5/-2 之间的区别。对于正常的 atan,它们看起来都像 2.5
我有一个 2D side-view shooter-thingy 需要重新审视。我目前正在研究瞄准,它部分起作用:枪口速度已知,重力已知,并且到目标的 x,y 距离也是已知的。使用 SE 和维基百科上的各种资源,我想出了以下计算射弹速度起始向量的方法:
public Vector2 calculateAim(Vector2 pos, Unit target) {
// Check if previous calculation can be recycled
if (target.equals(lastTarget))
return lastAim.cpy();
lastTarget = target;
double v = RifleBullet.projectileSpeed; // Muzzle velocity
double g = Settings.gravity.y; // Gravity, positive value
double x = offset.x; // x distance to target. Negative if towards left
double y = offset.y; // y distance to target. Negative if lower
double theta = Math.atan(((v * v) - Math.sqrt((v*v*v*v) - (g*(g*(x*x) + 2*y*(v*v))))) / (g * x));
Vector2 aim = new Vector2(-(float)Math.cos(theta), (float)Math.sin(theta));
aim.nor();
aim.scl((float)RifleBullet.projectileSpeed);
lastAim = aim.cpy();
return aim;
}
以上部分有效:最右边的人会正确瞄准。然而,站在左边的那个人一直在向错误的方向开火。看起来 Y 分量是正确的,但 X 分量完全颠倒了。如果我在计算 theta 之后添加:
if (side.contains("left"))
angleInRadians += Math.PI;
...它们都可以正确开火,但是在很长一段时间内都不可行 运行 因为战场上会有更多的单位,当我到达那个点时它肯定会引起问题。
我认为问题的根源可能是 Math.atan()
函数,因为我没有任何检查来查看三角计算中假设三角形的方向。
我应该如何改进我的方法,以便无论谁left/right/up/down都能正常工作?
Tenfour04 说的很有帮助。您可能想要使用 Math.atan2(y,x)
而不是 Math.atan(y/x)
请注意,您不是自己进行除法,而是将 y 和 x 作为单独的参数给出。这是 atan2 知道 5/2 和 -5/-2 之间的区别。对于正常的 atan,它们看起来都像 2.5