分子の衝突

def collision(self): #衝突の判定と処理
if(self.exist==True): #自分自身が存在している場合
for n in range(self.id+1, pnumber): #自分のidより後ろの全ての分子について
if(b[n].exist==True): #相手の分子が存在している場合
dvx = self.vx-b[n].vx #x方向の相対速度
dvy = self.vy-b[n].vy #y方向の相対速度
for ry in [-1,0,1]: #y方向の隣のコピーについても計算
for rx in [-1,0,1]: #x方向の隣のコピーについても計算
dx = self.x-(b[n].x+rx*grtor(width)) #x方向の位置の差
dy = self.y-(b[n].y+ry*grtor(height)) #y方向の位置の差
distance = sqrt(dx**2+dy**2) #2分子間の距離
if(distance < (self.d+b[n].d)/2.0): #両者の距離が半径の和より近い
self.R = 255 #自分の色を赤くする
self.G = 0
self.B = 0
b[n].R = 255 #相手の色も赤くする
b[n].G = 0
b[n].B = 0

if((dvx*dx+dvy*dy)<=0.0): #近づいているかどうか
#相対速度ベクトルと相対位置ベクトルの内積から、
#分子が近づいているか(負)、遠ざかっているか(正)がわかる
#分子が衝突半径内にあり、かつ遠ざかっているときのみ衝突処理をする
angle = atan2(dy, dx) #粒子間のなす角を算出
# 速度を衝突方向の水平成分(v1h,v2h)と垂直成分(v1v,v2v)に分ける
v1h = self.vx*cos(angle)+self.vy*sin(angle)
v1v = self.vx*sin(angle)-self.vy*cos(angle)
v2h = b[n].vx*cos(angle)+b[n].vy*sin(angle)
v2v = b[n].vx*sin(angle)-b[n].vy*cos(angle)
# 垂直成分(v1v,v2v)はそのまま
# 水平成分(v1h,v2h)は運動量保存則から新しい値を計算
nv1h = (self.m*v1h-b[n].m*v1h+2.0*b[n].m*v2h)/(self.m+b[n].m)
nv2h = (2.0*self.m*v1h-self.m*v2h+b[n].m*v2h)/(self.m+b[n].m)
# 速度の水平成分、垂直成分を画面上のx成分、y成分に書き戻す
self.vx = nv1h*cos(angle)+v1v*sin(angle)
self.vy = nv1h*sin(angle)-v1v*cos(angle)
b[n].vx = nv2h*cos(angle)+v2v*sin(angle)
b[n].vy = nv2h*sin(angle)-v2v*cos(angle)