将球从表面弹起
我目前正在编写像《Breakout》这样的游戏,我想知道如何才能正确地将球从表面弹起。
我采用了将速度旋转 90 度的天真的方法,即:
[vx, vy] -> [-vy, vx]
这(毫不奇怪)效果不太好。如果我知道球的位置和速度,以及球将击中的点(但会反弹),我怎样才能将球从该点反弹?
约束:
- 我使用整数数学(无 FP 任何地方)
- 我所有的表面都很简单 平坦的表面(垂直, 水平,或块)
- 我只想以 90 度角反弹
- 所有碰撞都是纯弹性的(这是突破 - 不需要摩擦等)
我不需要任何特定于语言的代码。如果有人可以提供一个关于如何正确执行此操作的小数学公式,那对我来说效果很好。
谢谢!
I'm currently in the middle of writing a game like Breakout, and I was wondering how I could properly bounce a ball off a surface.
I went with the naive way of rotating the velocity by 90 degrees, which was:
[vx, vy] -> [-vy, vx]
Which (unsurprisingly) didn't work so well. If I know the position and veocity of the ball, as well as the point the ball would hit (but is going to instead bounce off of) how can I bounce it off that point?
Constraints:
- I'm using integer math (No FP
anywhere) - All my surfaces are simple
flat surfaces (Vertical,
horizontal, or a block) - I only want to bounce off in a 90 degree angle
- All collisions are purely elastic (This is breakout -- No need to friction, etc)
I don't need any language specific code. If anyone could provide a small, mathematical formula on how to properly do this that would work fine for me.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
假设您只会从垂直或水平表面弹起,则可以分别取消 X 或 Y 方向上的速度。
所以,如果你有 [vx, vy],并且它从垂直的墙上反弹,你就会有 [-vx, vy]。
如果你有 [vx, vy],并且它从水平墙上反弹,你将得到 [vx, -vy]。
Assuming you are only going to be bouncing off of either vertical or horizontal surfaces, you can just negate the velocity in the X or Y directions, respectively.
So, if you have [vx, vy], and it bounces off a vertical wall, you will have [-vx, vy].
If you have [vx, vy], and it bounces off a horizontal wall, you will have [vx, -vy].
我会尝试 [vx, vy] -> [vx, -vy] 在水平墙上,[vx, vy] -> [-vx, vy] 在垂直墙壁上。
I'd try [vx, vy] -> [vx, -vy] on horizontal walls and [vx, vy] -> [-vx, vy] on vertical walls.
您需要计算接触点处的法向矢量。沿着法线的速度分量将改变方向,而垂直于法线的速度分量将保持不变。
对于水平/垂直表面,法线很容易计算。对于更复杂的表面,它可能取决于表面方程等。
此外,这假设球的能量不会改变。如果您考虑球的摩擦/热损失/旋转等,它可能会变得复杂。
You need to compute the normal vector at the point of contact. The component of the velocity along the normal will switch direction while the component of velocity perpendicular to the normal will remain the same.
For horizontal/vertical surfaces the normal is easy to calculate. For more complicated surfaces, it might depend on the equation of the surface etc.
Also, this assumes that the energy of the ball does not change. If you take friction/heat loss/rotation of ball etc into account it might get complicated.
您正在围绕垂直于撞击点表面的线反射矢量。在 2D 中:
退出角度 = 180 - 冲击角度。
You are reflecting the vector around a line perpendicular to the surface at the point of impact. in 2D:
exit_angle = 180 - impact_angle.
假设碰撞中没有能量损失,以速度 (vx, vy) 行进的球在从垂直表面弹起后将以 (vx, vy) 速度行进,从水平表面弹起后将以 (vx, -vy) 速度行进。
对于一般情况(从具有任意法向矢量的平面弹起,但仍然假设没有能量损失),请参阅计算部分下的这篇维基百科文章:http://en.wikipedia.org/wiki/Specular_reflection
Assuming no energy is lost in the collision, a ball travelling with speed (vx, vy) will travel with speed (-vx, vy) after bouncing off a vertical surface and (vx, -vy) after bouncing off a horizontal surface.
For the general case (bouncing off a plane with an arbitrary normal vector, still assuming no energy losses though) see this wikipedia article under the Calculation section: http://en.wikipedia.org/wiki/Specular_reflection
您需要了解球的表面和速度。例如,从平行于 x 轴的线弹起 [vx, vy] 将变为 [vx, -vy]。如果该线平行于 y 轴,则 [vx, vy] 将变为 [-vx, vy]。如果该线不平行于任一轴,则情况会更复杂,但您正在寻找沿表面方向性的速度的简单反射(对于 x, y 轴为 (1, 0) 和 (0, 1))。
You need to know the surface as well as the velocity of the ball. For instance bouncing off a line parallel to the x axis [vx, vy] would become [vx, -vy]. If the line is parallel to the y axis then [vx, vy] would become [-vx, vy]. It's more complicated if the line is not parallel to either axis, but you're looking for a simple reflection of velocity along the directionality of the surface ( (1, 0) and (0 , 1) for the x, y axes).
来自轴对齐框的 90 度反射只需适当反转 X/Y 速度符号即可。除此之外,它需要点积和一点向量旋转,但数学仍然非常安全 - 如果需要,可以很容易地作为定点完成。
90 degree reflections from axis aligned boxes is jst a matter of reversing X/Y velocity signs appropriately. Beyond that, it takes a dot product and a little vector twiddling, but that math is still very int safe - could easily be done as fixed point if need be.