如果我们假设没有空气阻力并且冲击是弹性的,这似乎很容易。在这种情况下,我们有一条曲线形成了我的两条抛物线。此外,这些抛物线的双导数在理想情况下必须是常数。
在 SO 中提出此类问题时,您确实需要添加数据示例、预期输出和您迄今为止尝试过的脚本示例。
我将使用数据为的情况
data = [(0,-16), (1,-9), (2,-4), (3,-1), (4,-2), (5,-5)]
预期输出为 3,因为球的方向在 data[3] 发生变化
我还将这些数据转换为更方便使用的形式:
xy = np.array(data)
这是可能的情况示例:
import numpy as np
import matplotlib.pyplot as plt
data = [(0,-16), (1,-9), (2,-4), (3,-1), (4,-2), (5,-5)]
xy = np.array(data)
fig = plt.figure(figsize=(8,3))
ax = plt.gca()
X = np.linspace(0, 3, 100)
Y = np.linspace(3, 5, 100)
sc1 = ax.scatter(*xy.T, s=25)
sc2 = ax.scatter(X, -(X-4)*(X-4), s=1)
sc3 = ax.scatter(Y, -1-(Y-3)*(Y-3), s=1)
plt.legend([sc1, sc2, sc3], ['frame positions', 'first parabola', 'second parabola'])
plt.show()
我们可以检查这个动作的各种属性:
velocity = np.diff(xy[:,1], prepend=np.nan) # [nan 7. 5. 3. -1. -3.]
acceleration = np.diff(velocity, prepend=np.nan) # [nan nan -2. -2. -4. -2.]
acceleration_jumps = np.diff(acceleration, prepend=np.nan) # [nan nan nan 0. -2. 2.]
我们可以看到运动的变化从样本(3,-1), (4,-2) 的索引 4 开始。这是一种跟踪它的方法:
rapid_jumps_mask = np.abs(acceleration_jumps)>0 # array([False, False, False, False, True, True])
rapid_jump_idx, = np.where(rapid_jumps_mask) # array([4, 5], dtype=int64)
最后,可以使用 rapid_jump_idx.tolist() 跟踪样本 ID,并返回 [4,5]。我预计是 3,但它有所不同,因为在样本 0-3 中没有观察到运动变化。
由于您的情况不理想,而且视图也不垂直,您可能还喜欢使用不同的边界来掩盖快速跳跃,如下所示:
rapid_jumps_mask = np.abs(acceleration_jumps) > 0.25