プログラミング言語「Python」で制作 Part117 | Photoshop CC Tutorials

今回はプログラミング言語の「Python」を使って作成しました。

 

下記の本のサンプル「振り子の衝突シミュレーション」をPygameで動くように移植しました。

 

■ プログラム

import traceback

try:
    import time,math,winsound

    import sys
    import math
    import random
    import pygame
    from pygame.locals import QUIT, KEYDOWN, K_LEFT, K_RIGHT, K_SPACE, Rect

    def array(N1, N2=0, N3=0):
        if N2 == 0 and N3==0: return [0 for i in range(N1)]
        elif N3 == 0: return [[0 for i in range(N2)] for j in range(N1)]
        else: return [[[0 for i in range(N3)] for j in range(N2)]
                      for k in range(N1)]

    PI=math.pi; PI3=PI/3
    Myu = 0.0           # 粘性抵抗
    e   = 1             # 衝突係数
    DT=0.05             # 時間刻み
    M1=10; M2=10        # 振り子のおもりの重さ
    R1=10; R2=10        # 振り子のおもり半径
    L=100               # 振り子の棒の長さ
    X0=120; Y0=10       # 振り子を吊るす位置の中心位置
    X1=X0-R1; X2=X0+R2  # 振り子を吊るす位置のX座標
    RID=array(2,2);TH=array(2);V=array(2)# 配列宣言
    TH[1]=PI3           # 振り子 2 のおもりの初期位置

    #--------------------------------------------------------------
    # メイン処理
    #--------------------------------------------------------------
    # Pygame初期設定
    pygame.init()
    SURFACE = pygame.display.set_mode((240, 150))
    FPSCLOCK = pygame.time.Clock()
    fps = 60

    #--------------------------------------------------------------
    # 振り子位置移動
    #--------------------------------------------------------------
    def movePend(SURFACE, X0, Y0, L, R, TH, col):
        X2=X0+L*math.sin(TH); Y2=Y0+L*math.cos(TH)
        pygame.draw.line(SURFACE, (255, 255, 255), (X0, Y0), (X2, Y2))
        pygame.draw.ellipse(SURFACE, col, (X2-R*2/2, Y2-R*2/2, R*2, R*2))

    #--------------------------------------------------------------
    # おもり衝突のチェック
    #--------------------------------------------------------------
    def checkCollision():
        global X1,X2, Y0, R1, R2; RR=R1+R2;RR=RR*RR
        XX1=X1+L*math.sin(TH[0]); YY1=Y0+L*math.cos(TH[0])
        XX2=X2+L*math.sin(TH[1]); YY2=Y0+L*math.cos(TH[1])
        DX=XX1-XX2; DY=YY2-YY1
        if DX*DX+DY*DY<=RR: return True
        return False

    #--------------------------------------------------------------
    # おもり衝突時の速度変更
    #--------------------------------------------------------------
    def Collision():
        global e, M1, M2; MM=M1+M2; ee=1+e ; VV=V[0]
        if abs(V[0]-V[1])>0.05: winsound.Beep(1026,50)
        V[0]+= M2*ee*(V[1]-VV)/MM
        V[1]-= M1*ee*(V[1]-VV)/MM

    #--------------------------------------------------------------
    # 衝突以外のおもりの移動の計算
    #--------------------------------------------------------------
    def calc():
        global V,TH,DT,Myu
        for i in range(2):
            V[i]-=DT*(math.sin(TH[i])+V[i]*Myu)
            TH[i]+=DT*V[i]
    
    #--------------------------------------------------------------
    # 振り子の描画
    #--------------------------------------------------------------
    def dsp(canvas):
        global RID,X1,X2, Y0,L,R1,R2,TH

        red = (255, 0, 0)
        blue = (0, 0, 255)
        movePend(SURFACE, X1,Y0, L,R1,TH[0], red)
        movePend(SURFACE, X2,Y0, L,R2,TH[1], blue)

    #--------------------------------------------------------------
    # ループ処理
    #--------------------------------------------------------------
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        #-----------------------------------------------------------
        # 描画処理
        #-----------------------------------------------------------
        SURFACE.fill((0, 0, 0))

        calc()
        dsp(SURFACE)
        if checkCollision():
            Collision()

        pygame.display.update()
        FPSCLOCK.tick(fps)

except Exception as e:
    print("エラー情報\n" + traceback.format_exc())

input()

 

■ 参考書

「Python 3.6 による 力学シミュレーション 第7巻: 複合運動」

 

■ ゲーム用ライブラリ

「Pygame」

 

■ プログラミング言語

「Python」