ルンゲ=クッタ法を用いて、卓球の速い打球の軌道をシミュレーションしてみる。
流体力学的効果を加味したモデルである。ただし、空気抵抗、マグヌス効果についてはこちらの文献を参考にした。
このシミュレーションは、対角線上のコースに、真の上回転をかけて、最大の速度で打ち出すモデルである。
コードはこちら。
#%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import math
#initial settings
N=300;dt=0.01;T=N*dt
x=[0]*N;y=[0]*N;z=[0]*N
dx=dy=dz=0.01
vx=[0]*N;vy=[0]*N;vz=[0]*N
#parameter
g=9.8;r=0.02;A=math.pi*(r**2);m=0.0027
h=0.1525;lx=1.525;ly=2.74
v=26
theta=math.pi/7.2
vh=v*math.cos(theta)
vv=v*math.sin(theta)
CD=0.5;CL=0.35;rho=1.293
x[0]=0;y[0]=0;z[0]=h
vx[0]=vh*lx/(lx**2+ly**2)**(1/2)
vy[0]=vh*ly/(lx**2+ly**2)**(1/2)
vz[0]=vv
def vnorm(a,b,c):
return (a**2+b**2+c**2)
def Fd(a,b,c,d):
return -1/2*CD*rho*A*vnorm(a,b,c)**(1/2)*d/m
def Flh(a,b,c,d):
return 1/2*CL*rho*A*(vnorm(a,b,c)**(1/2))*c*(d/(a**2+b**2)**(1/2))/m
def Flv(a,b,c):
return 1/2*CL*rho*A*(vnorm(a,b,c)**(1/2))*(a**2+b**2)**(1/2)/m
for i in range(N-1):
xk1=vx[i]*dt;yk1=vy[i]*dt;zk1=vz[i]*dt
vxk1=Fd(vx[i],vy[i],vz[i],vx[i])*dt+Flh(vx[i],vy[i],vz[i],vx[i])*dt
vyk1=Fd(vx[i],vy[i],vz[i],vy[i])*dt+Flh(vx[i],vy[i],vz[i],vy[i])*dt
vzk1=Fd(vx[i],vy[i],vz[i],vz[i])*dt-g*dt-Flv(vx[i],vy[i],vz[i])*dt
xk2=(vx[i]+vxk1/2)*dt;yk2=(vy[i]+vyk1/2)*dt;zk2=(vz[i]+vzk1/2)*dt
vxk2=Fd(vx[i]+vxk1/2,vy[i]+vyk1/2,vz[i]+vzk1/2,vx[i]+vxk1/2)*dt+Flh(vx[i]+vxk1/2,vy[i]+vyk1/2,vz[i]+vzk1/2,vx[i]+vxk1/2)*dt
vyk2=Fd(vx[i]+vxk1/2,vy[i]+vyk1/2,vz[i]+vzk1/2,vy[i]+vyk1/2)*dt+Flh(vx[i]+vxk1/2,vy[i]+vyk1/2,vz[i]+vzk1/2,vy[i]+vyk1/2)*dt
vzk2=Fd(vx[i]+vxk1/2,vy[i]+vyk1/2,vz[i]+vzk1/2,vz[i]+vzk1/2)*dt-g*dt-Flv(vx[i]+vxk1/2,vy[i]+vyk1/2,vz[i]+vzk1/2)*dt
xk3=(vx[i]+vxk2/2)*dt;yk3=(vy[i]+vyk2/2)*dt;zk3=(vz[i]+vzk2/2)*dt
vxk3=Fd(vx[i]+vxk2/2,vy[i]+vyk2/2,vz[i]+vzk2/2,vx[i]+vxk2/2)*dt+Flh(vx[i]+vxk2/2,vy[i]+vyk2/2,vz[i]+vzk2/2,vx[i]+vxk2/2)*dt
vyk3=Fd(vx[i]+vxk2/2,vy[i]+vyk2/2,vz[i]+vzk2/2,vy[i]+vyk2/2)*dt+Flh(vx[i]+vxk2/2,vy[i]+vyk2/2,vz[i]+vzk2/2,vy[i]+vyk2/2)*dt
vzk3=Fd(vx[i]+vxk2/2,vy[i]+vyk2/2,vz[i]+vzk2/2,vz[i]+vzk2/2)*dt-g*dt-Flv(vx[i]+vxk2/2,vy[i]+vyk2/2,vz[i]+vzk2/2)*dt
xk4=(vx[i]+vxk3)*dt;yk4=(vy[i]+vyk3)*dt;zk4=(vz[i]+vzk3)*dt
vxk4=Fd(vx[i]+vxk3,vy[i]+vyk3,vz[i]+vzk3,vx[i]+vxk3)*dt+Flh(vx[i]+vxk3,vy[i]+vyk3,vz[i]+vzk3,vx[i]+vxk3)*dt
vyk4=Fd(vx[i]+vxk3,vy[i]+vyk3,vz[i]+vzk3,vy[i]+vyk3)*dt+Flh(vx[i]+vxk3,vy[i]+vyk3,vz[i]+vzk3,vy[i]+vyk3)*dt
vzk4=Fd(vx[i]+vxk3,vy[i]+vyk3,vz[i]+vzk3,vz[i]+vzk3)*dt-g*dt-Flv(vx[i]+vxk3,vy[i]+vyk3,vz[i]+vzk3)*dt
x[i+1]=x[i]+(xk1+xk2*2+xk3*2+xk4)/6
y[i+1]=y[i]+(yk1+yk2*2+yk3*2+yk4)/6
z[i+1]=z[i]+(zk1+zk2*2+zk3*2+zk4)/6
vx[i+1]=vx[i]+(vxk1+vxk2*2+vxk3*2+vxk4)/6
vy[i+1]=vy[i]+(vyk1+vyk2*2+vyk3*2+vyk4)/6
vz[i+1]=vz[i]+(vzk1+vzk2*2+vzk3*2+vzk4)/6
ground=[0]*N
net=[ly/2]*30
high=[h*i/30 for i in range(30)]
target=[ly/2*i/N for i in range(N)]
distance=[ly*i/N for i in range(N)]
# xに対応するyの値を用意
#plt.plot(x,y,"r-..")
plt.plot(y,z,"g")
plt.plot(distance,ground,"b+")
plt.plot(target,ground,"r.")
plt.plot(net,high,"r.")
#plt.plot(time,y3,"b--")
#plt.plot(time,y4,"purple")
plt.xlabel("horizontal")
plt.ylabel("vertical")
plt.title("pingpong attack")
plt.xlim(-0.2,3.13)
plt.ylim(-0.76,1)
# plt.show()で画面に表示
plt.show()
6°の時
9°の時
なので、上手く入れるには、ラケットの面が6°~9°の間でないと行けない。
殆ど角度がぶれてはいけないことが分かった。
なので、強力なスマッシュを決めるということは、素早く上肢を動かしつつ、且つラケットの角度を精密にして(球の発射角度の誤差3°で!)打たなければならない。
非常に難しい。
バイバイ‼