Java:我的物体不会以0到45度之间的角度行进

时间:2015-02-04 00:54:48

标签: java math trigonometry degrees radians

一年多前我开始学习java,所以我还是很新的。

我试图让一个物体以恒定的净速度从一个点移动到另一个点,无论第二个点在帧中的哪个位置。目前,只要我每隔几帧运行一次该方法,它就能很好地工作。

唯一的问题是它只会水平移动,除非第二个点大约在45到135度之间或在225到315度之间(1 /2π和3 /2π或5 /2π和7 /2π)。 / p>

可能是因为'if'语句意味着阻止它除以0但看起来并不像。此外,如果有任何方法可以简化这些方程式或删除'if'语句,我也不会在那里提出一些建议。

注意:vel是物体行进的净速度,Prime.mx和Prime.my是目标点的位置。

public void target()
{ 
 if (Prime.mx > x)
 {
   if (Math.abs(x-Prime.mx) != 0)
     x = Math.round(Math.round((x + (vel*Math.cos(Math.atan(Math.abs(y-Prime.my)/Math.abs(x-Prime.mx)))))));
 }
 if (Prime.mx < x)
 {
   if (Math.abs(x-Prime.mx) != 0)
     x = Math.round(Math.round((x - (vel*Math.cos(Math.atan(Math.abs(y-Prime.my)/Math.abs(x-Prime.mx)))))));
 }
 if (Prime.my > y)
 {
   if (Math.abs(x-Prime.mx) != 0)
     y = Math.round(Math.round((y + (vel*Math.sin(Math.atan(Math.abs(y-Prime.my)/Math.abs(x-Prime.mx)))))));
 }
 if (Prime.my < y)
 {
   if (Math.abs(x-Prime.mx) != 0)
     y = Math.round(Math.round((y - (vel*Math.sin(Math.atan(Math.abs(y-Prime.my)/Math.abs(x-Prime.mx)))))));
 }
}

我使用Math.round两次,因为第一次将它从double传递到float,第二次使它成为int。我需要x和y作为整数,因此paint方法可以绘制对象。

我在网站上发现了一些类似的问题,但the closest one在python中,并且anwer似乎不适用于我的问题。

2 个答案:

答案 0 :(得分:1)

除了解决方案,这些都是一些建议。

首先,将所有坐标变量实现为浮点数,以防止舍入精度损失错误,并在绘制前仅进行舍入。

其次,从当前点定义float dx = Prime.mx - x; float dy = Prime.my - y;到目标的距离(稍后使用)。我会使用Math.atan2(dy,dx)来计算当前点和目标之间的角度。然后使用该角度增加坐标,如下所示:

x += Math.cos(angle)*vel;
y += Math.sin(angle)*vel;

第三,使用(dx*dx + dy*dy <= radius*radius)检查对象是否在目标位置以获得合适的半径(可以是1)。

另请注意,如果y轴下降,则角度将为CW(顺时针方向)而不是CCW(逆时针方向)。

答案 1 :(得分:1)

我相信你过于复杂了。如果您的起点为(sx, sy)且您的目的地为(dx, dy),那么您可以轻松计算沿着该行(x, y)距离的任何点p(0.0&lt; = p&lt; = 1.0)。您可以使用它以速度v移动。所以我建议找到你的终点,然后使用简单的算法在x和y轴上移动。

float dx = dist * Math.cos(angle);
float dy = dist * Math.sin(angle);
for (float p = 0.0; p <= 1.0; p = Math.min(1.0, p + dist / v) {
    x = sx + p * (dx - sx);
    y = sy + p * (dy - sy);
}

Math.min循环中的for表达式可确保您最终到达目的地点。

如果你已经有了目的地点,那就简单了。不是从dxdy找到distangle,而是使用毕达哥拉斯从distdx找到dy