粒子の衝突
粒子同士の弾性衝突を処理します。
#他の粒子との衝突処理 def interact(self): for n in range(0, ballnum): #他(自分自身のレプリカを含む)の粒子の相互作用を計算する for ix in range(-1, 2): #ix= -1, 0, 1 for iy in range(-1, 2): #iy = -1, 0, 1 if ix==0 and iy==0 and self.id==n: #自分自身との相互作用は計算しない pass else: ox = ball[n].x+ix*grtor(width) #相手のx座標 oy = ball[n].y+iy*grtor(height) #相手のy座標 dx = ox-self.x #相対位置 dy = oy-self.y dvx = ball[n].vx-self.vx #相対速度 dvy = ball[n].vy-self.vy r = math.sqrt(dx**2.0+dy**2.0) #距離 rn = r/(ball[n].r+self.r) #規格化した距離 if(rn<1.0): #衝突半径より近い if((dx*dvx+dy*dvy)<0.0): #近づいているとき (相対位置と相対速度の内積) #弾性衝突ルーチン #弾性係数 elast = 1.0 #粒子間のなす角を算出 angle = math.atan2(dy, dx) #速度を衝突方向の水平成分と垂直成分に分ける v1h = self.vx*math.cos(angle)+self.vy*math.sin(angle) v1v = self.vx*math.sin(angle)-self.vy*math.cos(angle) v2h = ball[n].vx*math.cos(angle)+ball[n].vy*math.sin(angle) v2v = ball[n].vx*math.sin(angle)-ball[n].vy*math.cos(angle) #垂直成分はそのまま #水平成分は運動量保存則と弾性係数から新しい値を計算する nv1h = (v2h-v1h)*(1+elast)/(self.m/ball[n].m+1.0)+v1h nv2h = (v1h-v2h)*(1+elast)/(ball[n].m/self.m+1.0)+v2h #速度の水平、垂直成分を画面上のx方向、y方向に書き戻す self.vx = nv1h*math.cos(angle)+v1v*math.sin(angle) self.vy = nv1h*math.sin(angle)-v1v*math.cos(angle) ball[n].vx = nv2h*math.cos(angle)+v2v*math.sin(angle) ball[n].vy = nv2h*math.sin(angle)-v2v*math.cos(angle)