今回はプログラミング言語の「Python」を使って作成しました。
下記の本のサンプルの「波のシミュレーション」をPygameで動くように移植しました。
■ プログラム
import traceback
try:
import sys
import math
import random
import pygame
from pygame.locals import QUIT, KEYDOWN, K_LEFT, K_RIGHT, K_SPACE, Rect
#■初期設定
NumX = 50; NumY = 50
Z=[[0 for j in range(NumY + 1)] for i in range(NumX + 1)]
ID=[[0 for j in range(NumY + 1)] for i in range(NumX + 1)]
ZX=[[0 for j in range(NumY + 1)] for i in range(NumX + 1)]
ZY=[[0 for j in range(NumY + 1)] for i in range(NumX + 1)]
def initHidden():
XY=[[0,0] for i in range(4)]
XY[0][0]=200;XY[0][1]=200; XY[1][0]=200;XY[1][1]=210
XY[2][0]=210;XY[2][1]=210; XY[3][0]=210;XY[3][1]=200
A=math.pi/9; B=math.pi/6; DX=5
cosA=DX*math.cos(A);cosB=DX*math.cos(B)
sinA=DX*math.sin(A);sinB=DX*math.sin(B)
for i in range(NumX+1):
for j in range(NumY+1):
ZX[i][j]=250+(i*cosA-j*cosB)
ZY[i][j]=250-(i*sinA+j*sinB)
for i in range(NumX):
for j in range(NumY):
XY2 = [(XY[0][0], XY[0][1]), (XY[1][0], XY[1][1]), (XY[2][0], XY[2][1]), (XY[3][0], XY[3][1])]
pygame.draw.polygon(SURFACE, (0, 100, 255), XY2)
pygame.draw.lines(SURFACE, (0, 0, 0), True, XY2)
#■隠れ線処理
def hiddenLine():
global canvas, NumX, NumY
XY=[0 for i in range(8)]
for i in range(NumX):
i2=NumX-i;i1=i2-1
for j in range(NumY):
j2=NumX-j; j1=j2-1
XY[0]=ZX[i1][j1]; XY[1]=ZY[i1][j1]-Z[i1][j1]
XY[2]=ZX[i1][j2]; XY[3]=ZY[i1][j2]-Z[i1][j2]
XY[4]=ZX[i2][j2]; XY[5]=ZY[i2][j2]-Z[i2][j2]
XY[6]=ZX[i2][j1]; XY[7]=ZY[i2][j1]-Z[i2][j1]
XY2 = [(XY[0], XY[1]), (XY[2], XY[3]), (XY[4], XY[5]), (XY[6], XY[7])]
pygame.draw.polygon(SURFACE, (0, 100, 255), XY2)
pygame.draw.lines(SURFACE, (0, 0, 0), True, XY2)
ZS=[[[0 for j in range(NumY+1)] for i in range(NumX+1)] for k in range(2)]
V =[[[0 for j in range(NumY+1)] for i in range(NumX+1)] for k in range(2)]
simTime = 0; ID1 = 0; ID2 = 1; Myu=0.02;counter=0
FreeBoundary=False # 境界条件を自由端にするときTrueにする
captMode= False #画面キャプチャするときTrueにする
def setData(): #データを設定
for j in range(NumX+1):
for k in range(NumY+1):
Z[j][k]=80.0*ZS[ID1][j][k]
def initWave():
global simTime, ID1, ID2, Myu,counter,XS,V
simTime = 0; ID1 = 0; ID2 = 1; Myu=0.02;counter=0
for i in range(NumX+1):
for j in range(NumY+1):
DX = i - NumX/2; DY = j - NumY/2
R = math.sqrt(DX * DX + DY * DY)
if R < 0.1: A=1
elif R > 3 : A=0
else : A = math.sin(R) / R;
ZS[0][ i][ j] = -A; V[0][ i][ j] = 0;
#print(i,j,ZS[0][ i][ j])
def waveEquation(SaveN, Alfa, DX, DT):
global NumX, NumY, ZS, ID1,ID2,simTime,Myu,counter
Beta = Alfa * Alfa / (DX * DX);
for k in range(SaveN):
for i in range(1, NumX):
for j in range(1, NumY):
ZS[ID2][i][j] = ZS[ID1][i][j] + DT * V[ID1][i][j]
for i in range(1, NumX):
for j in range(1, NumY):
Acc = Beta * (ZS[ID2][i][j + 1] - 2 * ZS[ID2][i][j] +
ZS[ID2][i][j - 1] + ZS[ID2][i + 1][j] -
2 * ZS[ID2][i][j] + ZS[ID2][i - 1][j])
V[ID2][i][j] = V[ID1][i][j] + DT *(Acc- Myu*V[ID1][i][j])
if FreeBoundary: #自由端境界条件
for i in range(NumX+1):
V [ID2][i][0] = V [ID2][i][1]
V [ID2][i][NumY] = V [ID2][i][NumY-1]
ZS[ID2][i][0] = ZS[ID2][i][1]
ZS[ID2][i][NumY] = ZS[ID2][i][NumY-1]
for i in range(NumY+1):
V [ID2][0][i] = V [ID2][1][i]
V [ID2][NumX][i] = V [ID2][NumX-1][i]
ZS[ID2][0][i] = ZS[ID2][1][i]
ZS[ID2][NumX][i] = ZS[ID2][NumX-1][i]
else: #固定端境界条件
for i in range(NumX+1):
V[ID2][i][0] =0; V[ID2][i][NumY]= 0
ZS[ID2][i][0]=0; ZS[ID2][i][NumY]=0
for i in range(NumY+1):
V[ID2][0][i] =0; V[ID2][NumX][i]=0
ZS[ID2][0][i]=0; ZS[ID2][NumX][i] = 0
simTime += DT; ID1 = ID2; ID2 = 1-ID2;counter+=1
return 0
def leftMouseDown(event):#ダウン
waveEquation(50, 0.05, 0.05, 0.01)
setData(); hiddenLine();
#■メイン処理
# Pygame初期設定
pygame.init()
SURFACE = pygame.display.set_mode((500, 300))
FPSCLOCK = pygame.time.Clock()
fps = 60
initHidden()
initWave()
if captMode:
waveEquation(50, 0.05, 0.05, 0.01)
setData(); hiddenLine();
else:
while(1):
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
#-----------------------------------------------------------
# 描画処理
#-----------------------------------------------------------
SURFACE.fill((0, 0, 0))
waveEquation(50, 0.05, 0.05, 0.01)
setData()
hiddenLine()
pygame.display.update()
FPSCLOCK.tick(fps)
except Exception as e:
print("エラー情報\n" + traceback.format_exc())
input()
■ 参考書
「Python 3.6 による 力学シミュレーション 第2巻: 振動」
■ ゲーム用ライブラリ
「Pygame」
■ プログラミング言語
「Python」