0

(在 Gosu 中使用 Ruby)

我有一个单点对象,代表一个朝某个方向看的人。

我有三个变量,,xy人的二维坐标)和@angle(他面对的方向,以度为单位)。如果我想找到x与该人前面的y距离正好为d(让我们设为 20)的点(在其他代码中,在他所面对的方向上的话),我该如何计算呢?

  def move
    # Move
    @x += @vel_x
    @y += @vel_y

    # HELP
    @point_in_front_of_me_x = # some_function_for_x(@x, @y, @angle)
    @point_in_front_of_me_y = # some_function_for_y(@x, @y, @angle)

    # Prevent window exit
    @x %= @window.width
    @y %= @window.height

    # Simulate air resistance
    @vel_x *= 0.95
    @vel_y *= 0.95
  end

如果您知道 Gosu 库或手动方式,都可以。如果您两者都知道并且可以指出好处,那就更好了!

4

1 回答 1

1

我不知道 Gosu 库(或它使用的坐标系),但手动解决方案是使用三角函数。您知道三角形的角度和斜边(h,移动的距离),并且您正在尝试计算 x 坐标(相邻边的长度,b)和 y 坐标(对边的长度,a)。

三角形

我们可以计算x_after_moving(使用以人的当前位置为中心的坐标系 - 如果需要,您应该能够轻松地将其调整到另一个坐标系)使用关系sin(angle)=opposite/hypotenuse和重新排列(我们这里只有一个未知数,对面 ( b)) :

def x_after_moving(distance, angle)
  distance * Math.sin(angle * Math::PI / 180)
end

我们乘以 pi/180 以将弧度(Ruby 所期望的)转换为度数。同样,知道了关系cos(angle)=adjacent/hypotenuse,我们可以使用类似的方法来计算新的 y 坐标:

def y_after_moving(distance, angle)
  distance * Math.cos(angle * Math::PI / 180)
end

验证它是否适用于以下内容:

p 'Angle 0 (straight up)'
p 'x:' + x_after_moving(20, 0).to_s + ', y:' + y_after_moving(20, 0).to_s
p 'Angle 90 (right)'
p 'x:' + x_after_moving(20, 90).to_s + ', y:' + y_after_moving(20, 90).to_s

给我们:

"Angle 0 (straight up)"
"x:0.0, y:20.0"
"Angle 90 (right)"
"x:20.0, y:1.2246467991473533e-15"

在某些情况下,您可能会得到非常小的值而不是零——四舍五入应该可以解决这个问题y_after_moving(20, 90).round

于 2015-02-12T20:52:13.070 回答