从 (x,y) 坐标列表中如何找到角度变化的点?
From a list of (x,y) coordinates how can I find the points where angle changes?
我有一个描述球在空中飞行的 (x,y) 坐标列表。从这个列表中,我想检测球在哪些点与墙壁接触,这会导致球的轨迹发生变化。
有没有办法根据这个列表找到围绕这个方向变化的点?
球穿过屏幕并接触墙壁时产生的轨迹。
如果我们假设没有空气阻力并且冲击是弹性的,这似乎很容易。在这种情况下,我们有一条曲线形成了我的两条抛物线。此外,这些抛物线的二重导数在理想情况下必须是常数。
在 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.]
我们可以看到运动变化在索引 4 处的样本 (3,-1), (4,-2)
之间开始。这是一种跟踪它的方法:
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()
和 returns [4,5]
跟踪样本 ID。我预计 3 但它不同,因为在样本 0-3 中没有观察到运动变化。
由于你的情况不理想,而且视图不垂直,你可能还想用不同的边界来掩盖快速跳跃,像这样:
rapid_jumps_mask = np.abs(acceleration_jumps) > 0.25
我有一个描述球在空中飞行的 (x,y) 坐标列表。从这个列表中,我想检测球在哪些点与墙壁接触,这会导致球的轨迹发生变化。
有没有办法根据这个列表找到围绕这个方向变化的点?
球穿过屏幕并接触墙壁时产生的轨迹。
如果我们假设没有空气阻力并且冲击是弹性的,这似乎很容易。在这种情况下,我们有一条曲线形成了我的两条抛物线。此外,这些抛物线的二重导数在理想情况下必须是常数。
在 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.]
我们可以看到运动变化在索引 4 处的样本 (3,-1), (4,-2)
之间开始。这是一种跟踪它的方法:
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()
和 returns [4,5]
跟踪样本 ID。我预计 3 但它不同,因为在样本 0-3 中没有观察到运动变化。
由于你的情况不理想,而且视图不垂直,你可能还想用不同的边界来掩盖快速跳跃,像这样:
rapid_jumps_mask = np.abs(acceleration_jumps) > 0.25