你如何在另一个向量上反映一个向量?

时间:2013-02-14 23:04:57

标签: actionscript-3 vector physics

我正在使用AS3为Flash游戏编写一些碰撞检测程序,并且无法弄清楚如何从一条线上弹出一个球。我跟踪一个代表球的2D速度的矢量,我试图将其反射到垂直于球与之碰撞的线(也就是正常线)的矢量上。我的问题是我不知道如何找出新的向量(这反映在正常情况下)。我想你可以使用Math.atan2找到法线和球的矢量之间的差异,但我不知道如何扩展它来解决我的问题。

3 个答案:

答案 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;