我正在尝试制作一个基本的台球游戏,并希望能够预测一杆球撞击另一个球后的去向。
首先,我认为需要计算球杆是否会撞击到任何物体,如果碰撞了,需要计算出碰撞点。我可以计算出直线和球的碰撞点,但是不知道两个球之间的碰撞点。
所以,给定2个球的x/y位置和速度,我该如何计算它们相撞的点?
(PS:我知道可以通过在每一步中计算两个球之间的距离来实现这一点,但我希望有更加优雅和高效的方法。)
设置示例:试图计算红点的位置:
我正在尝试制作一个基本的台球游戏,并希望能够预测一杆球撞击另一个球后的去向。
首先,我认为需要计算球杆是否会撞击到任何物体,如果碰撞了,需要计算出碰撞点。我可以计算出直线和球的碰撞点,但是不知道两个球之间的碰撞点。
所以,给定2个球的x/y位置和速度,我该如何计算它们相撞的点?
(PS:我知道可以通过在每一步中计算两个球之间的距离来实现这一点,但我希望有更加优雅和高效的方法。)
设置示例:试图计算红点的位置:
需要注意以下几点:
r
的球碰撞时,它们的中心点距离为 2r
。alpha
。现在你有一些几何问题要解决。
按照以下步骤进行构造:
A
。B
。AB
。A
沿着运动方向构造射线 R
。B
构造一个半径为 2r
的圆。B
垂直于 R
画出一条线段,将其相交点标记为 C
。AB
,可以用正弦定律找到 AB
和 R
之间的角度 alpha
,然后找到线段 BC
的长度。D
,再次使用正弦定律找到距离 AD 的长度。BD
的中点。现在你知道了一切。
从这些内容中构建高效代码需要自己动手实践。
顺便提一下——如果两个小球都在运动,这种构造方法是行不通的。但你可以转换到一个其中一个小球静止的参考系中来解决问题,然后再转回去。只要确保在逆变换之后解的结果位于允许的范围内就行了...
物理学家们总是会说出类似这样的评论。我试图抵制,但我真的做不到。
@dmckee的回答示意图如下:
编辑
针对@ArtB巫师的回答,上述图中D点的解决方案可以写成:
1/2 {(Ax+Bx+2 d Dx Cos[alpha]- Dx Cos[2 alpha]+ 2 Dy (Cos[alpha]-d) Sin[alpha]),
(Ay+By+2 d Dy Cos[alpha]- Dy Cos[2 alpha]- 2 Dx (Cos[alpha]-d) Sin[alpha])
}
在哪里
Dx = Ax - Bx
Dy = Ay - By
And
d = Sqrt[4 r^2 - (Dx^2 + Dy^2) Sin[alpha]^2]/Sqrt[Dx^2 + Dy^2]
HTH!
:=
)来区分显示我的工作和实际必要的代码。我使用标准的Y = mX + b
格式和准面向对象符号。我对段和结果线都使用BC。话虽如此,这应该是“几乎”可以复制粘贴的Python代码(删除“;”,用适当版本替换“sqrt”和“sqr”等)。
AB.m := (b.y - a.y) / (b.x - a.x);
AB.b := A.y - AB.m * A.x;
R.m := A.v.y / A.v.x;
R.b := A.y - R.m * A.x;
BC.m := -A.v.x/A.v.y;
这是垂直斜率的标准方程,BC.b := B.y - BC.m * B.x;
现在C是AB与BC相交的点,所以我们知道它们是相等的,因此让我们将C.y等于AB.m * C.x + AB.b == BC.m * C.x + BC.b;所以C.x := (AB.m - BC.M) / (BC.b - AB.b);
然后只需插入C.x
即可得到C.y := AB.m * C.x + AB.b;
BC
的长度,BC.l := sqrt( sqr(B.x-C.x) + sqr(B.y-C.y) );
BC.l > A.r + B.r
,则没有解,这些圆不相交,因为C是A相对于B的近地点。如果BC.l == A.r + B.r
,则只有一个解,即C == D。否则,如果BC.l < A.r + B.r
,则有两个解。您可以这样想,如果没有解,则子弹错过了,如果有一个解,则子弹擦伤了,如果有两个解,则既有入口又有出口。距离A更近的那个是我们想要的。D
是AC上距离B A.r + B.r
(也就是2r
)的点,因此:sqrt( sqr(D.x - B.x) + sqr(D.y - B.y) ) == 2r
sqr(D.x - B.x) + sqr(D.y - B.y) == 4*r*r
。现在有两个变量(即D.x
和D.y
)和一个方程式是麻烦的,但我们还知道D
在线上AC
上,因此D.y == AC.m*D.x + AC.b
。D.y
,得到sqr(D.x - B.x) + sqr(AC.m * D.x + AC.b - B.y) == 4*r*r
。sqr(D.x) + 2*D.x - sqr(B.x) + sqr(AC.m*D.x) + 2*AC.b*D.x - 2*AC.m*D.x*B.y + sqr(AC.b) - 2*AC.b*B.y + sqr(B.y) == 4*r*r
(这是我可能犯错的部分如果我真的犯错了)。我希望我只是为了卡尔玛或死灵法师徽章而发帖,但我真的需要解决这个问题,并想与大家分享。唉,我现在想躺下了。