计算撞到倾斜的墙壁后的角度变化

Bat*_*ash 1 javascript math

我正在用 javascript 制作一个游戏,其中一个对象应该从墙壁上反弹。我真的试图让它自己工作,但它从来没有正常工作。

假设有一个球在这个笼子里弹跳(蓝色 = 30°,棕色 = 60°);

笼子里的弹跳球

球的坐标是已知的。运动角度是已知的。碰撞点 (P) 坐标是已知的。墙的角度是已知的。球的位置正在使用以下函数在 setInterval 函数中更新它的坐标:

function findNewPoint(x, y, angle, distance) {
var result = {};

result.x =(Math.cos(angle * Math.PI / 180) * distance + x);
result.y = (Math.sin(angle * Math.PI / 180) * distance + y);

return result;
Run Code Online (Sandbox Code Playgroud)

所以,在碰撞时,应该有一个函数可以适当地改变球的角度。这似乎是一个非常复杂的问题,因为即使我知道墙是 30°,知道球从哪一侧撞到墙上也很重要。我尝试使用“平面中直线上的反射”公式以及一些向量,但它对我来说从来没有奏效。我不期待代码的完整答案,如果有人可以建议应该以何种方式对其进行编程,它也会有所帮助。

编辑:感谢您的提示,我意识到是什么引起了最大的混乱;如果我用鼠标在画布上选择一个角度,则起始坐标 (0,0) 位于左下角。但是由于画布的起始坐标在左上角,所以必须考虑这一点。

基本上使用这个公式来计算角度:

function angle(cx, cy, ex, ey) {
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx);
theta *= 180 / Math.PI; 
return theta;
Run Code Online (Sandbox Code Playgroud)

}

如果球从 (50,50) 移动到 (100,100),角度将为 -45。

现在,这个角度在撞击墙壁时会以下列方式变化: 角度反弹

老实说,我是通过反复试验得到这些的,我真的不明白为什么是 60 和 120。

MBo*_*MBo 5

使用角度来移动球并反复计算 Cos/Sin 是不明智的。而是使用具有以下分量的单位速度方向向量vx, vy

new_x = old_x + vx * Velocity_Magnitude * Time_Interval
Run Code Online (Sandbox Code Playgroud)

请注意 vx = Cos(angle), vy = Sin(angle),但使用方向方法,您很少需要使用三角函数。

角度为 Fi 的倾斜墙具有法线

nx = -Sin(Fi)
ny = Cos(Fi)
Run Code Online (Sandbox Code Playgroud)

要找到反射,您需要计算速度和法线的点积

dot = vx * nx + vy * ny
Run Code Online (Sandbox Code Playgroud)

反射变换后的速度:

vnewx = v.x - 2 * dot * n.x 
vnewy = v.y - 2 * dot * n.y 
Run Code Online (Sandbox Code Playgroud)

使用这些值进一步移动

(注意,可以同时使用内部法线和外部法线方向,因为方向翻转改变了两个组件,并且符号 2 * dot * n.x保持不变)

例子:

horizontal moving right
vx=1, vy=0   
30 degrees wall has normal 
nx=-1/2, ny=Sqrt(3)/2  
dot = -1/2
vnewx = 1 - 2 * (-1/2) * (-1/2) = 1/2
vnewy = 0 - 2 * (-1/2) * Sqrt(3)/2 = Sqrt(3)/2
(velocity direction angle becomes 60 degrees)

horizontal moving left
vx=-1, vy=0   
330 degrees wall (left bottom corner) has normal 
nx=1/2, ny=Sqrt(3)/2  
dot = -1/2
vnewx = -1 - 2 * (-1/2) * (1/2) = -1/2
vnewy = 0 - 2 * (-1/2) * (Sqrt(3)/2) = Sqrt(3)/2
(velocity direction angle becomes 120 degrees)
Run Code Online (Sandbox Code Playgroud)


Har*_*ens 5

这是一个函数,在给定入射角和表面角(以度为单位)的情况下返回反射角。它还确保返回角度在 0 到 359 度之间。

function angleReflect(incidenceAngle, surfaceAngle){
  var a = surfaceAngle * 2 - incidenceAngle;
  return a >= 360 ? a - 360 : a < 0 ? a + 360 : a;
}
Run Code Online (Sandbox Code Playgroud)

这是一个演示,其中蓝线是入射角,紫色线是反射角,黑线是表面。

反射角演示