计算 ball/point 的弹跳角度
Calculate the bouncing angle for a ball/point
我正在构建自己的小型游戏引擎以供学习。所以基本纯Java。我有由起点和终点(x 和 y 坐标)定义的线
现在我有了一个带有速度矢量的球。我想 "bounce" 离墙,它可以放置在任何可能的角度。碰撞发生后如何找出新的速度矢量?我知道点 S、P1 和 P2(见图)
我考虑过计算角度,并更改 x 和 y 分量。但我无法找到一种方法如何针对所有可能的角度执行此操作。
对于平行于 canvas 边界的墙,我可以找到很多解决方案,但没有通用的解决方案。 "big" 游戏引擎如何处理这个常见问题?
编辑:
我更新的 Vector class 方法:
public static Vector bounce(Vector normal, Vector velocity) {
Vector tmp = Vector.multiplication(2*Vector.dot(normal,velocity), normal);
return Vector.addition(tmp, velocity);
}
public static Vector multiplication(double multi, Vector n) {
Vector new_vector = new Vector(n.x * multi, n.y * multi);
return new_vector;
}
public static double dot(Vector a, Vector b) {
return a.x*b.x + a.y*b.y; // + a.z*b.z if you're in 3D
}
我的测试函数:
@Test
public void testBounce() {
Vector normal_vector_corrected = new Vector(0, 1);
Vector start_velocity = new Vector(3, -3);
Vector bounced_vector = Vector.bounce(normal_vector_corrected, start_velocity);
System.out.println("normal vector: "+normal_vector_corrected);
System.out.println("start_velocity: "+start_velocity);
System.out.println("bounced_vector "+bounced_vector);
}
输出是这样的:
normal vector: <Vector x=0,00, y=1,00>
start_velocity: <Vector x=3,00, y=-3,00>
bounced_vector <Vector x=3,00, y=-9,00>
根据我的计算,bounced_vector
应该是x=3,y=3。我的错误在哪里? (我的例子如图:)
编辑2:
我发现它必须是return Vec.add(tmp, v);
。此外,我必须反转速度矢量。
"bounced velocity vector"v'
由原始速度v
和表面法线单位向量n
得到[= =15=] 其中 .
代表 向量点积 。这通常称为反射;速度矢量反映在表面法线上。
如果您不熟悉这些术语,表面法线是垂直于表面(成 90 度角)的矢量。单位向量是长度为 1 的向量。
我假设您已经有一个 class 来表示向量,称为 Vec,具有将向量与标量相乘以及将两个向量相加的方法。您可以将反弹操作写为:
static Vec bounce(Vec n, Vec v) {
Vec tmp = Vec.scalarMultiply(-2*Vec.dot(n,v), n);
return Vec.add(tmp, v);
}
static double dot(Vec a, Vec b) {
return a.x*b.x + a.y*b.y; // + a.z*b.z if you're in 3D
}
至于如何让表面法线,那要看你是2D还是3D了。假设二维,很简单:如果 (x,y)
是从 P1 到 P2 的向量,那么 (-y,x)
垂直于它,并且 one 单位法线将是:
n = (-y/sqrt(x*x+y*y), x/sqrt(x*x+y*y))
另一个可能的正常单位是-n
。您将使用一个或另一个取决于您在表面的哪一侧。
您应该将法向量与场景的几何形状一起存储,这样您就不必每次都计算它。
我正在构建自己的小型游戏引擎以供学习。所以基本纯Java。我有由起点和终点(x 和 y 坐标)定义的线
现在我有了一个带有速度矢量的球。我想 "bounce" 离墙,它可以放置在任何可能的角度。碰撞发生后如何找出新的速度矢量?我知道点 S、P1 和 P2(见图)
我考虑过计算角度,并更改 x 和 y 分量。但我无法找到一种方法如何针对所有可能的角度执行此操作。
对于平行于 canvas 边界的墙,我可以找到很多解决方案,但没有通用的解决方案。 "big" 游戏引擎如何处理这个常见问题?
编辑:
我更新的 Vector class 方法:
public static Vector bounce(Vector normal, Vector velocity) {
Vector tmp = Vector.multiplication(2*Vector.dot(normal,velocity), normal);
return Vector.addition(tmp, velocity);
}
public static Vector multiplication(double multi, Vector n) {
Vector new_vector = new Vector(n.x * multi, n.y * multi);
return new_vector;
}
public static double dot(Vector a, Vector b) {
return a.x*b.x + a.y*b.y; // + a.z*b.z if you're in 3D
}
我的测试函数:
@Test
public void testBounce() {
Vector normal_vector_corrected = new Vector(0, 1);
Vector start_velocity = new Vector(3, -3);
Vector bounced_vector = Vector.bounce(normal_vector_corrected, start_velocity);
System.out.println("normal vector: "+normal_vector_corrected);
System.out.println("start_velocity: "+start_velocity);
System.out.println("bounced_vector "+bounced_vector);
}
输出是这样的:
normal vector: <Vector x=0,00, y=1,00>
start_velocity: <Vector x=3,00, y=-3,00>
bounced_vector <Vector x=3,00, y=-9,00>
根据我的计算,bounced_vector
应该是x=3,y=3。我的错误在哪里? (我的例子如图:)
编辑2:
我发现它必须是return Vec.add(tmp, v);
。此外,我必须反转速度矢量。
"bounced velocity vector"v'
由原始速度v
和表面法线单位向量n
得到[= =15=] 其中 .
代表 向量点积 。这通常称为反射;速度矢量反映在表面法线上。
如果您不熟悉这些术语,表面法线是垂直于表面(成 90 度角)的矢量。单位向量是长度为 1 的向量。
我假设您已经有一个 class 来表示向量,称为 Vec,具有将向量与标量相乘以及将两个向量相加的方法。您可以将反弹操作写为:
static Vec bounce(Vec n, Vec v) {
Vec tmp = Vec.scalarMultiply(-2*Vec.dot(n,v), n);
return Vec.add(tmp, v);
}
static double dot(Vec a, Vec b) {
return a.x*b.x + a.y*b.y; // + a.z*b.z if you're in 3D
}
至于如何让表面法线,那要看你是2D还是3D了。假设二维,很简单:如果 (x,y)
是从 P1 到 P2 的向量,那么 (-y,x)
垂直于它,并且 one 单位法线将是:
n = (-y/sqrt(x*x+y*y), x/sqrt(x*x+y*y))
另一个可能的正常单位是-n
。您将使用一个或另一个取决于您在表面的哪一侧。
您应该将法向量与场景的几何形状一起存储,这样您就不必每次都计算它。