技术背景
首先我们来看一下一个比赛画面,这是人民艺术家、弧圈大师许昕的一场比赛:
在这个视角下,我们可以很明显的看到乒乓球在空中划出来一道优美的弧线,这就是许昕拉出来的正手弧圈球。在其他的球类运动中,比如足球运动,也存在类似的现象,叫香蕉球或者弧旋球。关于这一现象的原理,我们一般解释为马格努斯效应。就是在球体的运动过程中,如果球体不仅仅是带有前进的速度,如果再加上一个球体自身的旋转,就会在流体中产生一个与角动量和速度平面相互垂直的作用力。具体公式可以参考如下由NASA提供的Kutta-Joukowski理论:
虽然Kutta-Joukowski理论一般是用来计算圆柱体的上升力的,但是相应的参数在计算球体的马格努斯力时也有非常好的效果。由于作者对流体力学领域知之甚少,如有错误欢迎流体力学领域大佬指正。
模拟马格努斯力
根据Kutta-Joukowski理论,我们可以写一个Python程序用来迭代乒乓球运动的过程,给乒乓球一个向前运动的初始速度,再给其一个适当的旋转角速度。这里我们先不考虑空气阻尼等问题,并且为了明显的看到弧圈效果,这里我们是采用了一个俯视图的二维视角。关于乒乓球的一些参数,比如半径是用的20mm,对应于当下的40+大球。重量的话不同的厂家和有缝球无缝球、训练球和比赛球等都有些许重量差异,一般在2.53g~2.70g之间,在模拟的时候我们使用了最轻的重量来模拟。由于马格努斯力会随着乒乓球运动轨迹的改变而改变,因此这里采用了一个迭代计算的过程,具体代码如下所示:
import numpy as np
from tqdm import trange
import matplotlib.pyplot as plt
r = 0.02
rho = 1.29
mass_min = 2.53e-03
mass_max = 2.70e-03
# Equation for force of lift
def F(vel, omega):
return 4*(4*np.pi**2*r**3*omega*vel*rho)/3
vel0 = np.array([-3.,10.])
omega0 = 10
s0 = np.array([0.,0.])
f0 = 0.
steps = 100
dt = 0.01
s = [s0.copy()]
for step in trange(steps):
s0 += vel0*dt+0.5*f0*dt**2/mass_min
s.append(s0.copy())
vel0 += np.array([np.sqrt(vel0[1]**2*(f0*dt/mass_min)**2/(vel0[0]**2+vel0[1]**2)),
-np.sqrt(vel0[0]**2*(f0*dt/mass_min)**2/(vel0[0]**2+vel0[1]**2))])
f0 = F(np.linalg.norm(vel0), np.abs(omega0))
s = np.array(s)
plt.figure()
plt.plot(s[:,0], s[:,1], 'o', color='orange')
plt.savefig('pingpong.png')
运行完成后我们可以看到这样的一个效果:
需要提醒和注意的是,在这个模拟过程中我们给定的初速度是向左前方的,并不是向正前方。可以看到,在马格努斯力的作用下,乒乓球的弧圈效果是非常明显的。
初始速度的大小对弧圈有什么影响?
为了方便测试,我们将上一个章节中用到的代码进行了模块化:
import numpy as np
from tqdm import trange
import matplotlib.pyplot as plt
r = 0.02
rho = 1.29
mass_min = 2.53e-03
mass_max = 2.70e-03
vel0 = np.array([-3., 10.])
omega0 = 10
s0 = np.array([0.,0.])
f0 = 0.
steps = 100
dt = 0.01
def F(vel, omega, r, rho):
return 4*(4*np.pi**2*r**3*omega*vel*rho)/3
def Trace(steps, s0, vel0, f0, dt, mass, omega0, r, rho):
s = [s0.copy()]
tmps = s0.copy()
for step in trange(steps):
tmps += vel0*dt+0.5*f0*dt**2/mass
s.append(tmps.copy())
vel0 += np.array([np.sqrt(vel0[1]**2*(f0*dt/mass)**2/(vel0[0]**2+vel0[1]**2)),
-np.sqrt(vel0[0]**2*(f0*dt/mass)**2/(vel0[0]**2+vel0[1]**2))])
f0 = F(np.linalg.norm(vel0), np.abs(omega0), r, rho)
return np.array(s)
s = Trace(steps, s0, vel0, f0, dt, mass_min, omega0, r, rho)
vel1 = np.array([-4.5, 15.])
s1 = Trace(steps, s0, vel1, f0, dt, mass_min, omega0, r, rho)
vel2 = np.array([-1.5, 5.])
s2 = Trace(steps, s0, vel2, f0, dt, mass_min, omega0, r, rho)
plt.figure()
plt.plot(s[:,0], s[:,1], 'o', color='orange')
plt.plot(s1[:,0], s1[:,1], 'o', color='blue')
plt.plot(s2[:,0], s2[:,1], 'o', color='black')
plt.savefig('pingpong.png')
在这段代码中我们测试了两个新的变量:将速度放大1.5倍(用蓝色表示)和将速度缩小到原来的0.5倍(用黑色表示),在不改变其角速度的情况下,得到的结果如下:
从这个结果来看,弧圈的弧度大小主要还是取决于角速度,跟乒乓球向前运动的速度本身没有太大的联系,但是如果只看局部的话,速度越快偏移越不明显。
角速度对弧圈有多大影响?
这次我们不改变速度和其他的变量,只调整角速度,来看看会有什么样的变化:
import numpy as np
from tqdm import trange
import matplotlib.pyplot as plt
r = 0.02
rho = 1.29
mass_min = 2.53e-03
mass_max = 2.70e-03
vel0 = np.array([-3., 10.])
omega0 = 10
s0 = np.array([0.,0.])
f0 = 0.
steps = 100
dt = 0.01
def F(vel, omega, r, rho):
return 4*(4*np.pi**2*r**3*omega*vel*rho)/3
def Trace(steps, s0, vel0, f0, dt, mass, omega0, r, rho):
s = [s0.copy()]
tmps = s0.copy()
for step in trange(steps):
tmps += vel0*dt+0.5*f0*dt**2/mass
s.append(tmps.copy())
vel0 += np.array([np.sqrt(vel0[1]**2*(f0*dt/mass)**2/(vel0[0]**2+vel0[1]**2)),
-np.sqrt(vel0[0]**2*(f0*dt/mass)**2/(vel0[0]**2+vel0[1]**2))])
f0 = F(np.linalg.norm(vel0), np.abs(omega0), r, rho)
return np.array(s)
s = Trace(steps, s0, vel0.copy(), f0, dt, mass_min, omega0, r, rho)
omega1 = 12.
s1 = Trace(steps, s0, vel0.copy(), f0, dt, mass_min, omega1, r, rho)
omega2 = 8.
s2 = Trace(steps, s0, vel0.copy(), f0, dt, mass_min, omega2, r, rho)
plt.figure()
plt.plot(s[:,0], s[:,1], 'o', color='orange')
plt.plot(s1[:,0], s1[:,1], 'o', color='blue')
plt.plot(s2[:,0], s2[:,1], 'o', color='black')
plt.savefig('pingpong.png')
这里我们将角速度也分别放大(蓝色轨迹)和缩小(黑色轨迹)来查看其中的差异,得到的结果如下:
这个图中所得到的结论也是比较符合我们的预期结果的,也就是说,角速度越大,球就越拐。
小球改大球的影响
我们网上一直有很多人在说大球改小球是对中国队的极大打击,这里面的影响其实可以分为两个部分来考虑:一是大球本身的旋球能力是否变弱了,二是制造大球的旋转是否比制造小球的旋转困难。其实第二问的回答几乎是肯定的,因为半径和重量发生了变化,在大球上要制造出跟小球相同的角速度和初始速度必然是更加困难的。而对于打法和姿势相对固定的运动员来说,绝对是一个巨大的打击。接下来我们通过程序来看看结果:
import numpy as np
from tqdm import trange
import matplotlib.pyplot as plt
r = 0.02
rho = 1.29
mass_min = 2.53e-03
mass_max = 2.70e-03
vel0 = np.array([-3., 10.])
omega0 = 10
s0 = np.array([0.,0.])
f0 = 0.
steps = 100
dt = 0.01
def F(vel, omega, r, rho):
return 4*(4*np.pi**2*r**3*omega*vel*rho)/3
def Trace(steps, s0, vel0, f0, dt, mass, omega0, r, rho):
s = [s0.copy()]
tmps = s0.copy()
for step in trange(steps):
tmps += vel0*dt+0.5*f0*dt**2/mass
s.append(tmps.copy())
vel0 += np.array([np.sqrt(vel0[1]**2*(f0*dt/mass)**2/(vel0[0]**2+vel0[1]**2)),
-np.sqrt(vel0[0]**2*(f0*dt/mass)**2/(vel0[0]**2+vel0[1]**2))])
f0 = F(np.linalg.norm(vel0), np.abs(omega0), r, rho)
return np.array(s)
s = Trace(steps, s0, vel0.copy(), f0, dt, mass_min, omega0, r, rho)
r = 0.019
mass = 2.5e-03
s1 = Trace(steps, s0, vel0.copy(), f0, dt, mass, omega0, r, rho)
r = 0.019
mass = 2.5e-03
omega0 = 12
s2 = Trace(steps, s0, vel0.copy(), f0, dt, mass_min, omega0, r, rho)
plt.figure()
plt.plot(s[:,0], s[:,1], 'o', color='orange')
plt.plot(s1[:,0], s1[:,1], 'o', color='blue')
plt.plot(s2[:,0], s2[:,1], 'o', color='black')
plt.savefig('pingpong.png')
在这次的测试中,我们采用了这样的两种对比方案:一是直接调整乒乓球的参数,而不改变速度与角速度的参数(蓝色轨迹),另一方面是调整乒乓球到小球,同时增大角速度(黑色轨迹),对比结果如下:
这个结果给我们传递的信息是,如果只是改了大球,但是能通过训练保持跟原本小球同等的初始速度和角速度的话,其实大球的轨迹曲率会更高,或者说轨迹更加的诡异。而就算是现在从大球换回小球,也需要在大球的角速度基础上增加20%的角速度,才有可能在小球上达到比大球下更拐的旋转。当然这些对比可能相对比较片面,仅仅可以作为一个效果参考。
总结概要
本文通过对马格努斯力的模拟,来理解乒乓球的弧圈原理。并且在这个理论基础之上对比了几种场景下的乒乓球轨迹,比如乒乓球的运动速度,或者日常所说的撞击对乒乓球轨迹的影响。还有乒乓球的角速度,也就是日常我们所说的摩擦对乒乓球轨迹的影响。还有一个在乒乓球界堪称变革的小球改大球对乒乓球这项运动可能带来的影响。由于这方面读过的理论文章较少,本文仅仅作为一个娱乐参考即可。
版权声明
本文首发链接为:https://www.cnblogs.com/dechinphy/p/pingpong.html
作者ID:DechinPhy
更多原著文章请参考:https://www.cnblogs.com/dechinphy/
打赏专用链接:https://www.cnblogs.com/dechinphy/gallery/image/379634.html
腾讯云专栏同步:https://cloud.tencent.com/developer/column/91958
参考链接
- www1.grc.nasa.gov/beginners-guide-to-aeronautics/ideal-lift-of-a-spinning-ball/