我正在使用AS3为Flash游戏编写一些碰撞检测程序,并且无法弄清楚如何从一条线上弹出一个球。我跟踪一个代表球的2D速度的矢量,我试图将其反射到垂直于球与之碰撞的线(也就是正常线)的矢量上。我的问题是我不知道如何找出新的向量(这反映在正常情况下)。我想你可以使用Math.atan2找到法线和球的矢量之间的差异,但我不知道如何扩展它来解决我的问题。
答案 0 :(得分:5)
矢量代数 - 你想要“反弹”矢量:
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;
答案 1 :(得分:1)
可以使用投影张量计算来自任何维度中具有正常 n 的线/(超 - )表面的任何向量 v 的镜像反射。 v 在 n 上的并行投影为: v || =( v 。 n ) n = v 。的ン即可。这里 nn 是法线与其自身的外(或张量)积。在笛卡尔坐标系中,它是一个包含元素的矩阵:nn[i,j] = n[i]*n[j]
。垂直投影只是原始矢量与其平行投影之间的差异: v - v ||。当矢量被反射时,其平行投影被反转,同时保持垂直投影。所以反射的矢量是:
v '= - v || +( v - v ||)= v - 2 v || = v 。 (我 - 2 nn )= v 。 R ( n ),其中
R ( n )= 我 - 2 nn
( I 是标识张量,在笛卡尔坐标中只是对角线单位矩阵 diag(1))
R 称为反射张量。在笛卡尔坐标系中,它是一个真实的对称矩阵,其中包含R[i,j] = delta[i,j] - 2*n[i]*n[j]
,delta[i,j] = 1
如果i == j
则为0
。它对于 n :
R ( - n )= 我 - 2( - n )( - n )= 我 - 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
查找球将击中线/墙的确切位置更为复杂 - 请参阅here。
答案 2 :(得分:0)
计算向量的两个组成部分。
一个组件是将矢量投影到反射表面上,另一个组件将投影到曲面的法线上(您说您已经拥有)。使用点积来获得投影。通过对两个向量求和将这两个组件加在一起。你会得到答案。
您甚至可以将第二个分量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;