【问题标题】:Programming 3d particle collision编程 3d 粒子碰撞
【发布时间】:2012-11-29 21:15:47
【问题描述】:

我的代码中有两个粒子在弹性碰撞中发生碰撞。我知道这两个粒子的质量和半径。我知道两个粒子碰撞时的中心点。我知道两个粒子的速度(包括方向)。我想弄清楚碰撞后两个粒子的速度(包括方向),我想以一种有效的方式计算它。我知道这更像是一个物理问题,而不是计算机编程问题,但程序员似乎总是更善于找到最有效的做事方式。我正在用 C++ 编程。我会很感激我能得到的任何帮助,即使只是指出我正确的方向。感谢您的帮助!

【问题讨论】:

  • 我读过this Way Back 刚出来的时候,IIRC 它是准确且有用的。但作为题外话结束。

标签: 3d simulation collision particles


【解决方案1】:

精确解可以通过数学软件(Mathematica、sagemath..等)求解。这里我使用了python包sympy。该算法采用Gröbner基和Buchberger算法,可以求解多项式方程组。

弹性碰撞方程是 1) 动量守恒,每个一维 2) 能量守恒。 3) 碰撞后第一个粒子的速度在指定单位向量的方向上

方程式如下所示:

uij :碰撞前第 i 个粒子的速度的第 j 个分量。
vij :碰撞后第 i 个粒子的速度的第 j 个分量。
n : 指向第一个粒子碰撞后速度方向的单位向量
t : 碰撞后第一个粒子的速度大小
米:质量

from sympy import *

u11,u12,u13 = symbols('u11 u12 u13')
u21,u22,u23 = symbols('u21 u22 u23')
v11,v12,v13 = symbols('v11 v12 v13')
v21,v22,v23 = symbols('v21 v22 v23')
n1,n2,n3,t= symbols('n1 n2 n3 t')
m1,m2 = symbols('m1 m2')


p1 = m1*u11 +m2*u21 - m1*v11 -m2*v21
p2 = m1*u12 +m2*u22 - m1*v12 -m2*v22
p3 = m1*u13 +m2*u23 - m1*v13 -m2*v23

e = m1*(u11**2+ u12**2 +u13**2) + m2*(u21**2+ u22**2+ u23**2) \
-( m1*(v11**2+ v12**2 +v13**2) + m2*(v21**2+ v22**2+ v23**2 ))

d1 =v11 - t*n1
d2 =v12 - t*n2
d3 =v13 - t*n3


s = solve([p1,p2,p3,e,d1,d2,d3], v11,v12,v13,v21,v22,v23,t, set=True)

解决方案是:[t, v11, v12, v13, v21, v22, v23]

2*sqrt(-m1**2*n1**2*u12**2 - m1**2*n1**2*u13**2 + 2*m1**2*n1*n2*u11*u12 + 2*m1**2*n1*n3*u11*u13 - m1**2*n2**2*u11**2 - m1**2*n2**2*u13**2 + 2*m1**2*n2*n3*u12*u13 - m1**2*n3**2*u11**2 - m1**2*n3**2*u12**2 - 2*m1*m2*n1**2*u12*u22 - 2*m1*m2*n1**2*u13*u23 + 2*m1*m2*n1*n2*u11*u22 + 2*m1*m2*n1*n2*u12*u21 + 2*m1*m2*n1*n3*u11*u23 + 2*m1*m2*n1*n3*u13*u21 - 2*m1*m2*n2**2*u11*u21 - 2*m1*m2*n2**2*u13*u23 + 2*m1*m2*n2*n3*u12*u23 + 2*m1*m2*n2*n3*u13*u22 - 2*m1*m2*n3**2*u11*u21 - 2*m1*m2*n3**2*u12*u22 + m2**2*n1**2*u11**2 - 2*m2**2*n1**2*u11*u21 + m2**2*n1**2*u12**2 - 2*m2**2*n1**2*u12*u22 + m2**2*n1**2*u13**2 - 2*m2**2*n1**2*u13*u23 + m2**2*n1**2*u21**2 + 2*m2**2*n1*n2*u21*u22 + 2*m2**2*n1*n3*u21*u23 + m2**2*n2**2*u11**2 - 2*m2**2*n2**2*u11*u21 + m2**2*n2**2*u12**2 - 2*m2**2*n2**2*u12*u22 + m2**2*n2**2*u13**2 - 2*m2**2*n2**2*u13*u23 + m2**2*n2**2*u22**2 + 2*m2**2*n2*n3*u22*u23 + m2**2*n3**2*u11**2 - 2*m2**2*n3**2*u11*u21 + m2**2*n3**2*u12**2 - 2*m2**2*n3**2*u12*u22 + m2**2*n3**2*u13**2 - 2*m2**2*n3**2*u13*u23 + m2**2*n3**2*u23**2)/(2*m1*n1**2 + 2*m1*n2**2 + 2*m1*n3**2 + 2*m2*n1**2 + 2*m2*n2**2 + 2*m2*n3**2) + (m1*n1*u11 + m1*n2*u12 + m1*n3*u13 + m2*n1*u21 + m2*n2*u22 + m2*n3*u23)/((m1 + m2)*(n1**2 + n2**2 + n3**2)) 


n1*(m1*n1*u11 + m1*n2*u12 + m1*n3*u13 + m2*n1*u21 + m2*n2*u22 + m2*n3*u23 + sqrt(-m1**2*n1**2*u12**2 - m1**2*n1**2*u13**2 + 2*m1**2*n1*n2*u11*u12 + 2*m1**2*n1*n3*u11*u13 - m1**2*n2**2*u11**2 - m1**2*n2**2*u13**2 + 2*m1**2*n2*n3*u12*u13 - m1**2*n3**2*u11**2 - m1**2*n3**2*u12**2 - 2*m1*m2*n1**2*u12*u22 - 2*m1*m2*n1**2*u13*u23 + 2*m1*m2*n1*n2*u11*u22 + 2*m1*m2*n1*n2*u12*u21 + 2*m1*m2*n1*n3*u11*u23 + 2*m1*m2*n1*n3*u13*u21 - 2*m1*m2*n2**2*u11*u21 - 2*m1*m2*n2**2*u13*u23 + 2*m1*m2*n2*n3*u12*u23 + 2*m1*m2*n2*n3*u13*u22 - 2*m1*m2*n3**2*u11*u21 - 2*m1*m2*n3**2*u12*u22 + m2**2*n1**2*u11**2 - 2*m2**2*n1**2*u11*u21 + m2**2*n1**2*u12**2 - 2*m2**2*n1**2*u12*u22 + m2**2*n1**2*u13**2 - 2*m2**2*n1**2*u13*u23 + m2**2*n1**2*u21**2 + 2*m2**2*n1*n2*u21*u22 + 2*m2**2*n1*n3*u21*u23 + m2**2*n2**2*u11**2 - 2*m2**2*n2**2*u11*u21 + m2**2*n2**2*u12**2 - 2*m2**2*n2**2*u12*u22 + m2**2*n2**2*u13**2 - 2*m2**2*n2**2*u13*u23 + m2**2*n2**2*u22**2 + 2*m2**2*n2*n3*u22*u23 + m2**2*n3**2*u11**2 - 2*m2**2*n3**2*u11*u21 + m2**2*n3**2*u12**2 - 2*m2**2*n3**2*u12*u22 + m2**2*n3**2*u13**2 - 2*m2**2*n3**2*u13*u23 + m2**2*n3**2*u23**2))/(m1*n1**2 + m1*n2**2 + m1*n3**2 + m2*n1**2 + m2*n2**2 + m2*n3**2)


n2*(m1*n1*u11 + m1*n2*u12 + m1*n3*u13 + m2*n1*u21 + m2*n2*u22 + m2*n3*u23 + sqrt(-m1**2*n1**2*u12**2 - m1**2*n1**2*u13**2 + 2*m1**2*n1*n2*u11*u12 + 2*m1**2*n1*n3*u11*u13 - m1**2*n2**2*u11**2 - m1**2*n2**2*u13**2 + 2*m1**2*n2*n3*u12*u13 - m1**2*n3**2*u11**2 - m1**2*n3**2*u12**2 - 2*m1*m2*n1**2*u12*u22 - 2*m1*m2*n1**2*u13*u23 + 2*m1*m2*n1*n2*u11*u22 + 2*m1*m2*n1*n2*u12*u21 + 2*m1*m2*n1*n3*u11*u23 + 2*m1*m2*n1*n3*u13*u21 - 2*m1*m2*n2**2*u11*u21 - 2*m1*m2*n2**2*u13*u23 + 2*m1*m2*n2*n3*u12*u23 + 2*m1*m2*n2*n3*u13*u22 - 2*m1*m2*n3**2*u11*u21 - 2*m1*m2*n3**2*u12*u22 + m2**2*n1**2*u11**2 - 2*m2**2*n1**2*u11*u21 + m2**2*n1**2*u12**2 - 2*m2**2*n1**2*u12*u22 + m2**2*n1**2*u13**2 - 2*m2**2*n1**2*u13*u23 + m2**2*n1**2*u21**2 + 2*m2**2*n1*n2*u21*u22 + 2*m2**2*n1*n3*u21*u23 + m2**2*n2**2*u11**2 - 2*m2**2*n2**2*u11*u21 + m2**2*n2**2*u12**2 - 2*m2**2*n2**2*u12*u22 + m2**2*n2**2*u13**2 - 2*m2**2*n2**2*u13*u23 + m2**2*n2**2*u22**2 + 2*m2**2*n2*n3*u22*u23 + m2**2*n3**2*u11**2 - 2*m2**2*n3**2*u11*u21 + m2**2*n3**2*u12**2 - 2*m2**2*n3**2*u12*u22 + m2**2*n3**2*u13**2 - 2*m2**2*n3**2*u13*u23 + m2**2*n3**2*u23**2))/(m1*n1**2 + m1*n2**2 + m1*n3**2 + m2*n1**2 + m2*n2**2 + m2*n3**2)


n3*(m1*n1*u11 + m1*n2*u12 + m1*n3*u13 + m2*n1*u21 + m2*n2*u22 + m2*n3*u23 + sqrt(-m1**2*n1**2*u12**2 - m1**2*n1**2*u13**2 + 2*m1**2*n1*n2*u11*u12 + 2*m1**2*n1*n3*u11*u13 - m1**2*n2**2*u11**2 - m1**2*n2**2*u13**2 + 2*m1**2*n2*n3*u12*u13 - m1**2*n3**2*u11**2 - m1**2*n3**2*u12**2 - 2*m1*m2*n1**2*u12*u22 - 2*m1*m2*n1**2*u13*u23 + 2*m1*m2*n1*n2*u11*u22 + 2*m1*m2*n1*n2*u12*u21 + 2*m1*m2*n1*n3*u11*u23 + 2*m1*m2*n1*n3*u13*u21 - 2*m1*m2*n2**2*u11*u21 - 2*m1*m2*n2**2*u13*u23 + 2*m1*m2*n2*n3*u12*u23 + 2*m1*m2*n2*n3*u13*u22 - 2*m1*m2*n3**2*u11*u21 - 2*m1*m2*n3**2*u12*u22 + m2**2*n1**2*u11**2 - 2*m2**2*n1**2*u11*u21 + m2**2*n1**2*u12**2 - 2*m2**2*n1**2*u12*u22 + m2**2*n1**2*u13**2 - 2*m2**2*n1**2*u13*u23 + m2**2*n1**2*u21**2 + 2*m2**2*n1*n2*u21*u22 + 2*m2**2*n1*n3*u21*u23 + m2**2*n2**2*u11**2 - 2*m2**2*n2**2*u11*u21 + m2**2*n2**2*u12**2 - 2*m2**2*n2**2*u12*u22 + m2**2*n2**2*u13**2 - 2*m2**2*n2**2*u13*u23 + m2**2*n2**2*u22**2 + 2*m2**2*n2*n3*u22*u23 + m2**2*n3**2*u11**2 - 2*m2**2*n3**2*u11*u21 + m2**2*n3**2*u12**2 - 2*m2**2*n3**2*u12*u22 + m2**2*n3**2*u13**2 - 2*m2**2*n3**2*u13*u23 + m2**2*n3**2*u23**2))/(m1*n1**2 + m1*n2**2 + m1*n3**2 + m2*n1**2 + m2*n2**2 + m2*n3**2)


(-m1**2*n1*n2*u12 - m1**2*n1*n3*u13 + m1**2*n2**2*u11 + m1**2*n3**2*u11 + m1*m2*n1**2*u11 - m1*m2*n1*n2*u22 - m1*m2*n1*n3*u23 + m1*m2*n2**2*u11 + m1*m2*n2**2*u21 + m1*m2*n3**2*u11 + m1*m2*n3**2*u21 - m1*n1*sqrt(-m1**2*n1**2*u12**2 - m1**2*n1**2*u13**2 + 2*m1**2*n1*n2*u11*u12 + 2*m1**2*n1*n3*u11*u13 - m1**2*n2**2*u11**2 - m1**2*n2**2*u13**2 + 2*m1**2*n2*n3*u12*u13 - m1**2*n3**2*u11**2 - m1**2*n3**2*u12**2 - 2*m1*m2*n1**2*u12*u22 - 2*m1*m2*n1**2*u13*u23 + 2*m1*m2*n1*n2*u11*u22 + 2*m1*m2*n1*n2*u12*u21 + 2*m1*m2*n1*n3*u11*u23 + 2*m1*m2*n1*n3*u13*u21 - 2*m1*m2*n2**2*u11*u21 - 2*m1*m2*n2**2*u13*u23 + 2*m1*m2*n2*n3*u12*u23 + 2*m1*m2*n2*n3*u13*u22 - 2*m1*m2*n3**2*u11*u21 - 2*m1*m2*n3**2*u12*u22 + m2**2*n1**2*u11**2 - 2*m2**2*n1**2*u11*u21 + m2**2*n1**2*u12**2 - 2*m2**2*n1**2*u12*u22 + m2**2*n1**2*u13**2 - 2*m2**2*n1**2*u13*u23 + m2**2*n1**2*u21**2 + 2*m2**2*n1*n2*u21*u22 + 2*m2**2*n1*n3*u21*u23 + m2**2*n2**2*u11**2 - 2*m2**2*n2**2*u11*u21 + m2**2*n2**2*u12**2 - 2*m2**2*n2**2*u12*u22 + m2**2*n2**2*u13**2 - 2*m2**2*n2**2*u13*u23 + m2**2*n2**2*u22**2 + 2*m2**2*n2*n3*u22*u23 + m2**2*n3**2*u11**2 - 2*m2**2*n3**2*u11*u21 + m2**2*n3**2*u12**2 - 2*m2**2*n3**2*u12*u22 + m2**2*n3**2*u13**2 - 2*m2**2*n3**2*u13*u23 + m2**2*n3**2*u23**2) + m2**2*n1**2*u21 + m2**2*n2**2*u21 + m2**2*n3**2*u21)/(m2*(m1*n1**2 + m1*n2**2 + m1*n3**2 + m2*n1**2 + m2*n2**2 + m2*n3**2))


(m1**2*n1**2*u12 - m1**2*n1*n2*u11 - m1**2*n2*n3*u13 + m1**2*n3**2*u12 + m1*m2*n1**2*u12 + m1*m2*n1**2*u22 - m1*m2*n1*n2*u21 + m1*m2*n2**2*u12 - m1*m2*n2*n3*u23 + m1*m2*n3**2*u12 + m1*m2*n3**2*u22 - m1*n2*sqrt(-m1**2*n1**2*u12**2 - m1**2*n1**2*u13**2 + 2*m1**2*n1*n2*u11*u12 + 2*m1**2*n1*n3*u11*u13 - m1**2*n2**2*u11**2 - m1**2*n2**2*u13**2 + 2*m1**2*n2*n3*u12*u13 - m1**2*n3**2*u11**2 - m1**2*n3**2*u12**2 - 2*m1*m2*n1**2*u12*u22 - 2*m1*m2*n1**2*u13*u23 + 2*m1*m2*n1*n2*u11*u22 + 2*m1*m2*n1*n2*u12*u21 + 2*m1*m2*n1*n3*u11*u23 + 2*m1*m2*n1*n3*u13*u21 - 2*m1*m2*n2**2*u11*u21 - 2*m1*m2*n2**2*u13*u23 + 2*m1*m2*n2*n3*u12*u23 + 2*m1*m2*n2*n3*u13*u22 - 2*m1*m2*n3**2*u11*u21 - 2*m1*m2*n3**2*u12*u22 + m2**2*n1**2*u11**2 - 2*m2**2*n1**2*u11*u21 + m2**2*n1**2*u12**2 - 2*m2**2*n1**2*u12*u22 + m2**2*n1**2*u13**2 - 2*m2**2*n1**2*u13*u23 + m2**2*n1**2*u21**2 + 2*m2**2*n1*n2*u21*u22 + 2*m2**2*n1*n3*u21*u23 + m2**2*n2**2*u11**2 - 2*m2**2*n2**2*u11*u21 + m2**2*n2**2*u12**2 - 2*m2**2*n2**2*u12*u22 + m2**2*n2**2*u13**2 - 2*m2**2*n2**2*u13*u23 + m2**2*n2**2*u22**2 + 2*m2**2*n2*n3*u22*u23 + m2**2*n3**2*u11**2 - 2*m2**2*n3**2*u11*u21 + m2**2*n3**2*u12**2 - 2*m2**2*n3**2*u12*u22 + m2**2*n3**2*u13**2 - 2*m2**2*n3**2*u13*u23 + m2**2*n3**2*u23**2) + m2**2*n1**2*u22 + m2**2*n2**2*u22 + m2**2*n3**2*u22)/(m2*(m1*n1**2 + m1*n2**2 + m1*n3**2 + m2*n1**2 + m2*n2**2 + m2*n3**2))


(m1**2*n1**2*u13 - m1**2*n1*n3*u11 + m1**2*n2**2*u13 - m1**2*n2*n3*u12 + m1*m2*n1**2*u13 + m1*m2*n1**2*u23 - m1*m2*n1*n3*u21 + m1*m2*n2**2*u13 + m1*m2*n2**2*u23 - m1*m2*n2*n3*u22 + m1*m2*n3**2*u13 - m1*n3*sqrt(-m1**2*n1**2*u12**2 - m1**2*n1**2*u13**2 + 2*m1**2*n1*n2*u11*u12 + 2*m1**2*n1*n3*u11*u13 - m1**2*n2**2*u11**2 - m1**2*n2**2*u13**2 + 2*m1**2*n2*n3*u12*u13 - m1**2*n3**2*u11**2 - m1**2*n3**2*u12**2 - 2*m1*m2*n1**2*u12*u22 - 2*m1*m2*n1**2*u13*u23 + 2*m1*m2*n1*n2*u11*u22 + 2*m1*m2*n1*n2*u12*u21 + 2*m1*m2*n1*n3*u11*u23 + 2*m1*m2*n1*n3*u13*u21 - 2*m1*m2*n2**2*u11*u21 - 2*m1*m2*n2**2*u13*u23 + 2*m1*m2*n2*n3*u12*u23 + 2*m1*m2*n2*n3*u13*u22 - 2*m1*m2*n3**2*u11*u21 - 2*m1*m2*n3**2*u12*u22 + m2**2*n1**2*u11**2 - 2*m2**2*n1**2*u11*u21 + m2**2*n1**2*u12**2 - 2*m2**2*n1**2*u12*u22 + m2**2*n1**2*u13**2 - 2*m2**2*n1**2*u13*u23 + m2**2*n1**2*u21**2 + 2*m2**2*n1*n2*u21*u22 + 2*m2**2*n1*n3*u21*u23 + m2**2*n2**2*u11**2 - 2*m2**2*n2**2*u11*u21 + m2**2*n2**2*u12**2 - 2*m2**2*n2**2*u12*u22 + m2**2*n2**2*u13**2 - 2*m2**2*n2**2*u13*u23 + m2**2*n2**2*u22**2 + 2*m2**2*n2*n3*u22*u23 + m2**2*n3**2*u11**2 - 2*m2**2*n3**2*u11*u21 + m2**2*n3**2*u12**2 - 2*m2**2*n3**2*u12*u22 + m2**2*n3**2*u13**2 - 2*m2**2*n3**2*u13*u23 + m2**2*n3**2*u23**2) + m2**2*n1**2*u23 + m2**2*n2**2*u23 + m2**2*n3**2*u23)/(m2*(m1*n1**2 + m1*n2**2 + m1*n3**2 + m2*n1**2 + m2*n2**2 + m2*n3**2))

【讨论】:

    【解决方案2】:

    我向您推荐 Pixar 发布的 paper。它是关于刚体的模拟,并包含一些代码,因此您可以试一试! :-)

    Here你也可以下载一些处理3D运动的C++代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 2022-01-12
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      相关资源
      最近更新 更多