我正在使用 AS3 为 Flash 游戏编写一些碰撞检测程序,但在弄清楚如何将球从线上弹起时遇到了麻烦。我跟踪表示球的 2D 速度的向量,并试图将其反映在垂直于球碰撞线(也称为法线)的向量上。我的问题是我不知道如何找出新向量(这反映在法线上)。我认为您可以使用 Math.atan2 来查找法线向量和球向量之间的差异,但我不确定如何扩展它来解决我的问题。
3 回答
矢量代数 -你想要“反弹”矢量:
vec1 是球的运动矢量,vec2 是表面/线矢量:
// 1. Find the dot product of vec1 and vec2
// Note: dx and dy are vx and vy divided over the length of the vector (magnitude)
var dpA:Number = vec1.vx * vec2.dx + vec1.vy * vec2.dy;
// 2. Project vec1 over vec2
var prA_vx:Number = dpA * vec2.dx;
var prA_vy:Number = dpA * vec2.dy;
// 3. Find the dot product of vec1 and vec2's normal
// (left or right normal depending on line's direction, let's say left)
var dpB:Number = vec1.vx * vec2.leftNormal.dx + vec1.vy * vec2.leftNormal.dy;
// 4. Project vec1 over vec2's left normal
var prB_vx:Number = dpB * vec2.leftNormal.dx;
var prB_vy:Number = dpB * vec2.leftNormal.dy;
// 5. Add the first projection prA to the reverse of the second -prB
var new_vx:Number = prA_vx - prB_vx;
var new_vy:Number = prA_vy - prB_vy;
将这些速度分配给球的运动矢量并让它弹跳。
PS:
vec.leftNormal --> vx = vec.vy; vy = -vec.vx;
vec.rightNormal --> vx = -vec.vy; vy = vec.vx;
可以使用投影张量计算任何向量v从具有法线n在任何维度上的线/(超)曲面的镜面反射。v在n上的平行投影为:v || = ( v . n ) n = v。nn。这里nn是法线与自身的外(或张量)乘积。在笛卡尔坐标中,它是一个包含元素的矩阵:nn[i,j] = n[i]*n[j]
。垂直投影只是原始向量与其平行投影之间的差异:v - v||。当矢量被反射时,它的平行投影被反转,而垂直投影被保留。所以反射向量为:
v ' = - v || + ( v - v ||) = v - 2 v || = v。( I - 2 nn ) = v。R ( n ),其中
R ( n ) = I - 2 nn
(I是单位张量,在笛卡尔坐标中只是对角单位矩阵diag(1))
R称为反射张量。在笛卡尔坐标系中,它是一个具有分量的实对称矩阵R[i,j] = delta[i,j] - 2*n[i]*n[j]
,其中delta[i,j] = 1
ifi == j
和0
else。它也是关于n对称的:
R ( - n ) = I - 2(- n )(- n ) = I - 2 nn = R ( n )
因此,使用向外或向内的法线n并不重要- 结果是相同的。
在二维和笛卡尔坐标中,R
(R的矩阵表示)变为:
[ R00 R01 ] [ 1.0-2.0*n.x*n.x -2.0*n.x*n.y ]
R = [ ] = [ ]
[ R10 R11 ] [ -2.0*n.x*n.y 1.0-2.0*n.y*n.y ]
然后将反射向量的分量计算为行向量矩阵乘积:
v1.x = v.x*R00 + v.y*R10
v1.y = v.x*R01 + v.y*R11
或扩展后:
k = 2.0*(v.x*n.x + v.y*n.y)
v1.x = v.x - k*n.x
v1.y = v.y - k*n.y
在三个维度:
k = 2.0*(v.x*n.x + v.y*n.y + v.z*n.z)
v1.x = v.x - k*n.x
v1.y = v.y - k*n.y
v1.z = v.z - k*n.z
找到球击中线/墙的确切点更复杂 - 请参见此处。
计算向量的两个分量。
一个组件将是您的矢量在反射表面上的投影,另一个组件将是在表面法线上的投影(您说您已经拥有)。使用点积来获得投影。通过对两个向量求和来将这两个分量相加。你会有你的答案。
您甚至可以将第二个分量 A2 计算为原始向量减去第一个分量,因此:A2 = A - A1。然后你想要的向量是 A1 加上反射的 A2 (这只是 -A2 因为它垂直于你的表面)或:
Ar = A1-A2
或者
Ar = 2A1 - A 与 Ar = -(2A2 - A) 相同
如果 [Ax,Bx] 是你的球速度并且 [Wx,Wy] 是代表墙壁的单位向量:
A1x = (Ax*Wx+Ay*Wy)*Wx;
A1y = (Ax*Wx+Ay*Wy)*Wy;
Arx = 2*A1x - Ax;
Ary = 2*A1y - Ay;