#!/opt/local/bin/python #Andrew Samuels #baseball.py from scipy import * from pdb import * #create arrays dt = 1e-4 nMAX = int(1/dt) x = zeros(nMAX) y = zeros(nMAX) z = zeros(nMAX) vx = zeros(nMAX) vy = zeros(nMAX) vz = zeros(nMAX) v = zeros(nMAX) #constants B = 4.1e-4 #magnus force (dimensionless) w = 1800/60.0 * 2*pi #rotaton rate of baseball, 1800 rpm to rad/s g = 9.81 #acceleration of gravity (m/s^2) v0_fb = 42.4688 #initial speed of pitch, fastball (m/s) v0_op = 38.0 #initial speed of pitch, other pitches (m/s) l = 18.44 #distance from pitcher (m) T_fb = l/v0_fb #step-length, estimated flight time, fastball T_op = l/v0_op #step-length, estimated flight time, other pitches nT_fb = int(T_fb/dt) #number of iterations for fastball nT_op = int(T_op/dt) #number of iterations for other pitches d2r = pi/180 # convert degrees to radians theta = 1 * d2r # elevation angle of pitch, degrees phi1 = 225 * d2r #direction of w, relative to z, fastball phi2 = 45 * d2r #direction of w, relative to z, curveball phi3 = 0 * d2r #direction of w, relative to z, slider phi4 = 135 * d2r #direction of w, relative to z, screwball #drag force constants c1 = 0.0039 c2 = 0.0058 vd = 35.0 #(m/s) delta = 5.0 # (m/s) #initial conditions x[0] = 0.0 y[0] = 0.0 z[0] = 0.0 vx[0] = v0_fb * cos(theta) vy[0] = 0.0 vz[0] = v0_fb * sin(theta) #pass dx/dt=vx through runkut4 def rk4dx(vx,dt): def dxdt(vx): dxdt = vx return dxdt K0 = dt * dxdt(vx) K1 = dt * dxdt(vx + K0/2.0) K2 = dt * dxdt(vx + K1/2.0) K3 = dt * dxdt(vx + K2) vxnew = (K0 + 2.0*K1 + 2.0*K2 + K3)/6.0 return vxnew #pass dy/dt=vy through runkut4 def rk4dy(vy,dt): def dydt(vy): dydt = vy return dydt K0 = dt * dydt(vy) K1 = dt * dydt(vy + K0/2.0) K2 = dt * dydt(vy + K1/2.0) K3 = dt * dydt(vy + K2) vynew = (K0 + 2.0*K1 + 2.0*K2 + K3)/6.0 return vynew #pass dz/dt=vz through runkut4 def rk4dz(vz,dt): def dzdt(vz): dzdt = vz return dzdt K0 = dt * dzdt(vz) K1 = dt * dzdt(vz + K0/2.0) K2 = dt * dzdt(vz + K1/2.0) K3 = dt * dzdt(vz + K2) vznew = (K0 + 2.0*K1 + 2.0*K2 + K3)/6.0 return vznew #solve accelerations with runge kutta 4 def rk4(v,vx,vy,vz,dt,phi): def ax(v,vx,vy,vz,phi): #drag force function, Fd(v) def Fd(v): return c1 + (c2/(1.0 + exp((v-vd)/delta))) return -Fd(v)*v*vx + B*w*(vz*sin(phi)-vy*cos(phi)) def ay(v,vx,vy,phi): #drag force function, Fd(v) def Fd(v): return c1 + (c2/(1.0 + exp((v-vd)/delta))) return -Fd(v)*v*vy + B*w*vx*cos(phi1) def az(v,vx,vz,phi): #drag force function, Fd(v) def Fd(v): return c1 + (c2/(1.0 + exp((v-vd)/delta))) return -g*-Fd(v)*v*vz - B*w*vx*sin(phi) K0 = dt * ax(v,vx,vy,vz,phi) L0 = dt * ay(v,vx,vy,phi) M0 = dt * az(v,vx,vz,phi) K1 = dt * ax(v + dt/2.0,vx + K0/2.0,vy + L0/2.0,vz + M0/2.0,phi) L1 = dt * ay(v + dt/2.0,vx + K0/2.0,vy + L0/2.0,phi) M1 = dt * az(v + dt/2.0,vx + K0/2.0,vz + M0/2.0,phi) K2 = dt * ax(v + dt/2.0,vx + K1/2.0,vy + L1/2.0,vz + M1/2.0,phi) L2 = dt * ay(v + dt/2.0,vx + K1/2.0,vy + L1/2.0,phi) M2 = dt * az(v + dt/2.0,vx + K1/2.0,vz + M1/2.0,phi) K3 = dt * ax(v + dt,vx + K2,vy + L2,vz + M0,phi) L3 = dt * ay(v + dt,vx + K1,vy + L2,phi) M3 = dt * az(v + dt,vx + K1,vz + M2,phi) axnew = (K0 + 2.0*K1 + 2.0*K2 + K3)/6.0 aynew = (L0 + 2.0*L1 + 2.0*L2 + L3)/6.0 aznew = (M0 + 2.0*M1 + 2.0*M2 + M3)/6.0 return axnew,aynew,aznew f=open('fastball.dat','w') #first time step is n + 1 #start loop for i in range(0,nT_fb): v = (vx[i] * vx[i] + vy[i] * vy[i] + vz[i] * vz[i]) v = (v)**0.5 print "X: " + str(x[i]) + " , Y: " + str(y[i]) + " , Z: " + str(z[i]) + " ,T: " + str(x[i]/v) +" , V: "+ str(v) + "\n" f.write(str(x[i])+'\t'+str(y[i])+'\t'+ str(z[i])+'\t'+str(x[i]/v) + '\t' + str(v) +'\n') x[i+1] = x[i] + rk4dx(vx[i],dt) y[i+1] = y[i] + rk4dy(vy[i],dt) z[i+1] = z[i] + rk4dz(vz[i],dt) vx[i+1] = vx[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi1)[0] vy[i+1] = vy[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi1)[1] vz[i+1] = vz[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi1)[2] f.close() print "Created fastball.dat" #change initial conditions for the other pitches vx[0] = v0_op * cos(theta) vz[0] = v0_op * sin(theta) #curveball h=open('curveball.dat','w') for i in range(0,nT_op): v = (vx[i] * vx[i] + vy[i] * vy[i] + vz[i] * vz[i]) v = (v)**0.5 print "X: " + str(x[i]) + " , Y: " + str(y[i]) + " , Z: " + str(z[i]) + " ,T: " + str(x[i]/v) +" , V: "+ str(v) + "\n" h.write(str(x[i])+'\t'+str(y[i])+'\t'+ str(z[i])+'\t'+str(x[i]/v) + '\t' + str(v) +'\n') x[i+1] = x[i] + rk4dx(vx[i],dt) y[i+1] = y[i] + rk4dy(vy[i],dt) z[i+1] = z[i] + rk4dz(vz[i],dt) vx[i+1] = vx[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi2)[0] vy[i+1] = vy[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi2)[1] vz[i+1] = vz[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi2)[2] h.close() print "Created curveball.dat" #slider j=open('slider.dat','w') for i in range(0,nT_op): v = (vx[i] * vx[i] + vy[i] * vy[i] + vz[i] * vz[i]) v = (v)**0.5 print "X: " + str(x[i]) + " , Y: " + str(y[i]) + " , Z: " + str(z[i]) + " ,T: " + str(x[i]/v) +" , V: "+ str(v) + "\n" j.write(str(x[i])+'\t'+str(y[i])+'\t'+ str(z[i])+'\t'+str(x[i]/v) + '\t' + str(v) +'\n') x[i+1] = x[i] + rk4dx(vx[i],dt) y[i+1] = y[i] + rk4dy(vy[i],dt) z[i+1] = z[i] + rk4dz(vz[i],dt) vx[i+1] = vx[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi3)[0] vy[i+1] = vy[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi3)[1] vz[i+1] = vz[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi3)[2] j.close() print "Created slider.dat" #screwball o=open('screwball.dat','w') for i in range(0,nT_op): v = (vx[i] * vx[i] + vy[i] * vy[i] + vz[i] * vz[i]) v = (v)**0.5 print "X: " + str(x[i]) + " , Y: " + str(y[i]) + " , Z: " + str(z[i]) + " ,T: " + str(x[i]/v) +" , V: "+ str(v) + "\n" o.write(str(x[i])+'\t'+str(y[i])+'\t'+ str(z[i])+'\t'+str(x[i]/v) + '\t' + str(v) +'\n') x[i+1] = x[i] + rk4dx(vx[i],dt) y[i+1] = y[i] + rk4dy(vy[i],dt) z[i+1] = z[i] + rk4dz(vz[i],dt) vx[i+1] = vx[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi4)[0] vy[i+1] = vy[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi4)[1] vz[i+1] = vz[i] + rk4(v,vx[i],vy[i],vz[i],dt,phi4)[2] o.close() print "Created screwball.dat"
I am a software engineer with a computational physics focus. The purpose of this blog is to showcase my ideas and works. I can create value and reduce costs for your company.
20111228
Fun with Python: Simulating Baseball Pitches using 4th Order Runge-Kutta Method
Here is a description of the problem in PDF format. Basically this code simulates four different baseball pitches (slider, curve, fastball, screwball) by solving differential equations using the 4th order Runge-Kutta method.