0

我正在尝试实现一个球在 4 个垂直壁之间弹跳的动画,即球的速度恒定。问题是,我使用的框架要求我在每次与墙壁碰撞时告诉球的起点和终点。

在碰撞的那一刻,我可以访问球当前和之前与墙壁接触的位置。给定墙壁的坐标 x_min、x_max、y_min 和 y_max,以及球的这两个位置,计算下一个位置的最简单方法是什么?

我想到的所有算法都遵循一种蛮力方法,有许多 if-else 语句……我想知道是否有一些优雅的方法来处理这个问题。

4

3 回答 3

1

[对不起,这是不完整的 - 我会发布它作为评论,但它太大并且涉及 ascii 艺术。我以后可能会删除它。]

如果您想要一种紧凑、优雅的方法,则可能更容易将球想象成一条直线,穿过重复的矩形图案。

+------+------+--*---+
|      |      | *    |
|      |      |*     |
+------+------*------+
|      |     *|      |
|      |    * |      |
+------+---*--+------+
|      |  *   |      |
|      | *    |      |
+------+*-----+------+
|      *      |      |
|     *|      |      |
+----*-+------+------+
|   *  |      |      |
|  *   |      |      |
+-*----+------+------+

(您需要反映矩形,然后“免费”获得反弹)。

我很确定你可以使用类似于bresenham 算法的东西 来计算交点。

[感谢投票,但我不得不说,我认为这可能是一个痛苦的世界。跟踪反射,特别是如果恰好碰到角落,会很棘手......有时使用丑陋的代码更容易!]

于 2013-10-20T01:16:18.053 回答
1

我不确定这是否与您的想法相似,但我的想法是基本上像没有墙一样计算位置,然后以墙为中心点翻转适用的坐标。

所以,首先你计算:

new
 \
  \
   \
---------
     \
      \
      old

然后你把它翻译成:

---------
   / \
  /   \
 /    old
new

伪代码:

newX = oldX + xInc
newY = oldY + yInc

if newX < 0
  newX = -newX

if newY < 0
  newY = -newY

if newX > maxX
  newX = maxX - (newX - maxX)
  // or 2*maxX - newX

if newY > maxY
  newY = maxY - (newY - maxY)
  // or 2*maxY - newY
于 2013-10-20T02:26:27.017 回答
1

假设之前的反弹在位置 (x_min, y_prev) 处离开左壁,而当前反弹在 (x_curr, y_max) 处离开顶壁。下一次反弹应该在 (x_max, y_next) 处离开右侧墙壁,其中:

y_next = y_max - (y_max - y_prev) * (x_max - x_curr) / (x_curr - x_min)

这是简单的几何图形,由(上一次反弹、左上角、当前反弹)定义的三角形与三角形(当前反弹、右上角、下一次反弹)相似(形状相同但大小不同)。像这样:

+--*----+
| / \   |
|/   \  |
*     \ |
|      \|
|       *
|       |
+-------+

如果 y_next 小于 y_min,这意味着球会先于右墙撞到底墙。将在 (x_next, y_min) 发生,其中:

x_next = x_curr + (x_curr - x_min) * (y_max - y_min) / (y_max - y_prev)

像这样的东西:

+--*------+
| / \     |
|/   \    |
*     \   |
|      \  |
+-------*-+
于 2013-10-20T00:13:33.383 回答