如何有效地计算将在盒子中移动并在其墙壁上弹跳(2D)的点的未来位置?

How to efficiently compute the future position of a point that will move in a box and bounce on its walls (2D)?

我这里有一个简单的 maths/physics 问题:在笛卡尔坐标系中,我有一个以已知速度随时间移动的点。该点位于一个盒子内,并在其壁上正交反弹。

这是我在绘画上做的一个简单示例:

我们所知道的:红点位置,以及由角度 θ 和速度定义的速度。我们当然知道绿盒子的尺寸。

在例子中,我用黄色画出了它的大概轨迹,假设经过一段已知的确定时间后,红点在蓝点上。计算蓝点位置的最有效方法是什么?

我一直在努力用三角函数和矢量投影计算每个“反弹点”,但我觉得这是一种资源浪费,因为三角函数通常非常耗费处理器资源。我将有超过一千个点需要这样计算,所以我真的需要找到一种更有效的方法。

如果有人有任何想法,我将不胜感激。

你不需要一直使用三角函数。取而代之的是将归一化方向向量作为 (dx, dy) = (cos(θ), sin(θ))

从垂直墙反弹后,x 分量改变了它的符号 dx = -dx,从水平墙反弹后,y 分量改变了它的符号 dy = -dy。你可以看到计算非常简单。

如果您(出于奇怪的原因)更喜欢使用角度,请使用角度变换(对于非零半径的球)

if ((ball.x + ball.radius) >= window.width || (ball.x - ball.radius) <= 0)
        ball.theta = M_PI - ball.theta;
  else
     if ((ball.y + ball.radius) >= window.height || (ball.y - ball.radius) <= 0) 
           ball.theta = - ball.theta;

获得弹跳点:

Starting point (X0, Y0)
Ray angle Theta, c = Cos(Theta), s = Sin(Theta);
Rectangle coordinates: bottom left (X1,Y1), top right (X2,Y2)

if c >= 0 then //up
  XX = X2
else
  XX = X1

if s >= 0 then  //right
  YY = Y2
else
  YY = Y1

if c = 0 then //vertical ray
   return Intersection = (X0, YY)

if s = 0 then  //horizontal ray
   return Intersection = (XX, Y0)

tx = (XX - X0) / c   //parameter when vertical edge is met
ty = (YY - Y0) / s   //parameter when horizontal edge is met

if tx <= ty then  //vertical first
    return Intersection = (XX, Y0 + tx * s)
else            //horizontal first
    return  Intersection = (X0 + ty * c, YY)

除了编程方面的考虑,从几何角度来看,它还有一个有趣的解决方案。可以在不考虑0<t<T

期间的时间轨迹的情况下,找到特定时间T的点的位置

一分钟,忘记盒子的大小和边界;并假设该点可以永远沿直线移动。然后该点具有恒定速度分量 vx = v*cos(θ), vy = v*sin(θ) 并且在时间 T 虚拟 部分将是 x' = x0 + vx * T, y' = y0 + vy * T

现在您需要映射虚拟位置(x',y')到实际位置(x,y)。见下图

您可以递归地反映虚拟点 w.r.t 边界,直到该点返回到参考(初始)框中。这才是重点。现在的问题是如何做这些数学?以及如何找到 (x,y) 知道 (x',y')?

ab 分别表示框沿 xy 的大小。然后 nx = floor(x'/a)ny = floor(y'/b) 表示该点与参考框的距离以框数表示。另外dx = x'-nx*ady = y'-ny*b介绍了虚拟点在其虚拟框内的相对位置。

现在你可以找到真正的位置(x,y):如果nx是偶数,那么x = dx else x = a-dx;同样,如果 ny 是偶数,则 y = dy 否则 y = b-dy。换句话说,在x轴和y轴上的偶数次反射,使真实点和虚拟点处于相同的相对位置,而奇数次反射使它们不同且互补。