粒子の衝突

粒子の衝突

粒子同士の弾性衝突を処理します。

    #他の粒子との衝突処理
    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)