计算圆的速度

Calculating a circle's velocity

这个问题我已经研究了一段时间了,看起来并不难,但是我越来越累了,而且越试越复杂(但它可能真的很容易) .

我的目标是让一个球从另一个球弹回。看起来很简单。

球 2 由用户的鼠标控制(到目前为止它有点像单人乒乓球,但它是一个圆形而不是矩形)所以它的速度无关紧要。

球 1 有一些属性,包括 dx(它每帧移动的 x 距离)和 dy(dx,但用于 y 坐标)

我目前遇到的问题是您不知道哪些值是正值哪些是负值(因此速度会立即严重增加或减少),您可以使用以下方法解决此问题还有很多如果,但我现在太困惑了,无法思考。

下面是这个函数的重要部分。另外,我试着设置它,使 dx + dy 始终相同,即使数字发生变化,这样看起来更自然。

if (collision(ball, paddle)) {
    diffX = paddle.x-ball.x;
    diffY = paddle.y-ball.y;
    totalVel = ball.dx+ball.dy;
    dir = {
      x : diffX/(diffX+diffY)*-totalVel,
      y : diffY/(diffX+diffY)*-totalVel
    };
    ball.dx = dir.x;
    ball.dy = dir.y;
  }

这是一个包含完整代码的 JSFiddle https://jsfiddle.net/a2prr0uw/1/

所以首先让我们从定义什么是"bounce"开始——速度是一样的,但是方向(在两个轴上)将被反转。如果我们把dx和dy当成一个向量,那么我们可以先这样得到球的传入速度:

var ballSpeed = Math.sqrt((ball.dx * ball.dx) + (ball.dy * ball.dy));

无论 dx 和 dy 在做什么,以上值始终为正。

接下来,我们需要球的传入方向 - 该位与您当前所获得的相同:

diffX = paddle.x-ball.x;
diffY = paddle.y-ball.y;

然而,如果我们也将其视为一个向量,它基本上具有完全未知的长度。所以,让我们对其进行归一化,使其成为长度为 1 的方向向量:

var distanceBetweenPaddleAndBall = Math.sqrt((diffX * diffX) + (diffY * diffY));
diffX /= distanceBetweenPaddleAndBall;
diffY /= distanceBetweenPaddleAndBall;

diffX 和 diffY 现在是归一化方向向量 - 球当前进入的方向 - 而 ballSpeed 是我们希望它前进的速度。

现在我们将应用弹跳 - 翻转方向并保持速度。变成这样:

dir = {
  x : -diffX * ballSpeed,
  y : -diffY * ballSpeed
};

把它们放在一起,我们得到这样的结果:

if (collision(ball, paddle)) {
    diffX = paddle.x-ball.x;
    diffY = paddle.y-ball.y;
    // How fast is the ball coming in?
    var ballSpeed = Math.sqrt((ball.dx * ball.dx) + (ball.dy * ball.dy));
    // How far is the ball from the paddle?
    var distanceBetweenPaddleAndBall = Math.sqrt((diffX * diffX) + (diffY * diffY));

    // Normalise diffX and diffY so we have a direction vector:
    diffX /= distanceBetweenPaddleAndBall;
    diffY /= distanceBetweenPaddleAndBall;

    // Apply the bounce and the original ball speed:
    dir = {
      x : -diffX * ballSpeed,
      y : -diffY * ballSpeed
    };
    ball.dx = dir.x;
    ball.dy = dir.y;
  }

here it is as a fork of your fiddle too.

不是答案,而是关于弹跳逻辑的一些注意事项:

  • 你必须计算球的方向 (dy/dx)
  • 碰撞也有一个方向(两个中心之间的角度= b.x-p.x / b.y-p.y)
  • 弹跳后的角度要根据这两个角度来计算:用第二个做镜像
  • 要计算碰撞后新的 dx 和 dy,您需要原始速度 Math.abs(Math.sqrt(Math.pow(dx)+Math.pow(dy)) ) 的球
  • 根据这个速度和新的方向你可以计算出新的 dx & dy