Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

碰撞求解(一):使用向量 #34

Open
phenomLi opened this issue Aug 7, 2019 · 0 comments
Open

碰撞求解(一):使用向量 #34

phenomLi opened this issue Aug 7, 2019 · 0 comments

Comments

@phenomLi
Copy link
Owner

phenomLi commented Aug 7, 2019

碰撞求解是紧接着碰撞检测后的一个步骤,顾名思义就是对发生碰撞的对象进行碰撞反应的模拟,比如反弹旋转等。碰撞求解可以说是物理引擎里最难的部分之一了,但是放心,这篇文章会先从最简单的向量部分入门,利用简单的向量知识,模拟简单的碰撞效果。


该文章只涉及少量简单数学,请放心食用。要求:

  • 高中向量知识

球与墙壁的碰撞

我们先从最基本的开始,考虑在理想情况下(无重力,阻力,完全弹性碰撞)有一些球在盒子里自由运动的情况:

其中箭头方向代表球的速度方向。


先不考虑球与球直接的碰撞,那么在盒子中,球只会与墙壁发生碰撞,通过碰撞不断改变球的速度方向(大小不变)。我们可以想象到,当球碰撞墙壁时,它的运动轨迹是这样的:

其中蓝色向量代表球碰撞前的速度,红色向量代表球碰撞后的速度。


所以显然的,要求解球碰撞墙壁后的速度方向就是要求红色向量。
为了求解红色的向量,我们可以对这次碰撞进行建模:


u代表碰撞前速度,v代表碰撞后速度,n代表碰撞法向,且uv关于n对称。碰撞法向n通常情况下不容易求得,但是由于现在情景简单,所以这里我们可以一眼看出n就是垂直与墙壁平面的向量。注意n是一个单位向量


现在un都是已知的,我们要做的就是用un去表示v。现在还是不好求出v,但我们可以把v平移到u的起点,然后延长n,延长后的n记为n'


这时,我们很容易得到一个关键等式:

所以只要求出n'就可以了。那么怎么求呢?观察发现,由于uv是等长的,uvn' 形成了一个等腰三角形,我们可以用投影解决。


首先,我们把u投影到n'上,得到1/2|n'|。

将结果乘上2便得到n'的模长,再由于n'和n
是共线的,且n为单位向量,所以只要将n乘上n'的模长即可求得n'


最后,我们把n'换一下,得到v关于un的表达式:


解决了。很简单。


其实整个流程要注意的只有一点,就是n的方向,如果n是指向墙壁外的,那么最后的表达式就要加号换成减号。

球与球的碰撞

有了上面的基础,求解球与球的碰撞就水到渠成了,只要解决两个问题就好:

  1. 确定碰撞法线n
  2. 墙壁是静止的,球与球是动态的,因此要考虑另一个球的情况:两个球在求解时的法线是相反的

球与球的碰撞法向其实也很简单,相信大家都能看出来是两个球圆心间的向量:

求得后将其单位化即可。


其次对于求解另一个球的v,只要取反向碰撞法向即可,也就是上面说到的加号变减号的情况。

最后

本文只是碰撞求解的入门,在物理引擎中使用上面的方案其实是不现实的,因为对象还包含旋转,摩擦力和非弹性碰撞,单一的求出速度并不能解决所有问题。本文旨在让大家了解什么是碰撞求解,以及对其有个大概的认识。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant