Python中曲率与弯曲的转换_python – numpy中的曲线曲率

编辑:我把这个答案放在一起几个小时,所以我错过了你最新的编辑,表明你只需要曲率.希望这个答案无论如何都会有所帮助.

除了做一些曲线拟合,我们的近似导数的方法是通过finite differences.谢天谢地,numpy有一个gradient方法为我们做这些差异计算,负责平均每个内点的前一个和下一个斜率的平均细节,并留下每个仅端点等

import numpy as np

a = np.array([ [ 0. , 0. ],[ 0.3 , 0. ],[ 1.25, -0.1 ],

[ 2.1 , -0.9 ],[ 2.85, -2.3 ],[ 3.8 , -3.95],

[ 5. , -5.75],[ 6.4 , -7.8 ],[ 8.05, -9.9 ],

[ 9.9 , -11.6 ],[ 12.05, -12.85],[ 14.25, -13.7 ],

[ 16.5 , -13.8 ],[ 19.25, -13.35],[ 21.3 , -12.2 ],

[ 22.8 , -10.5 ],[ 23.55, -8.15],[ 22.95, -6.1 ],

[ 21.35, -3.95],[ 19.1 , -1.9 ]])

现在,我们计算每个变量的导数并将它们放在一起(出于某种原因,如果我们只调用np.gradient(a),我们得到一个数组列表……不确定我的头顶是什么发生在那里,但我现在只是解决它):

dx_dt = np.gradient(a[:, 0])

dy_dt = np.gradient(a[:, 1])

velocity = np.array([ [dx_dt[i], dy_dt[i]] for i in range(dx_dt.size)])

这为我们提供了以下速度向量:

array([[ 0.3 , 0. ],

[ 0.625, -0.05 ],

[ 0.9 , -0.45 ],

[ 0.8 , -1.1 ],

[ 0.85 , -1.525],

[ 1.075, -1.725],

[ 1.3 , -1.925],

[ 1.525, -2.075],

[ 1.75 , -1.9 ],

[ 2. , -1.475],

[ 2.175, -1.05 ],

[ 2.225, -0.475],

[ 2.5 , 0.175],

[ 2.4 , 0.8 ],

[ 1.775, 1.425],

[ 1.125, 2.025],

[ 0.075, 2.2 ],

[-1.1 , 2.1 ],

[-1.925, 2.1 ],

[-2.25 , 2.05 ]])

当浏览一个散点图时,这是有道理的.

现在,为了速度,我们采用速度矢量的长度.但是,有一点我们在这里没有记住:一切都是t的功能.因此,ds / dt实际上是t的标量函数(与t的向量函数相反),就像dx / dt和dy / dt一样.因此,我们将ds_dt表示为每个第二个时间间隔的numpy值数组,每个值对应于每秒的速度近似值:

ds_dt = np.sqrt(dx_dt * dx_dt + dy_dt * dy_dt)

这会产生以下数组:

array([ 0.3 , 0.62699681, 1.00623059, 1.36014705, 1.74588803,

2.03254766, 2.32284847, 2.57512136, 2.58311827, 2.48508048,

2.41518633, 2.27513736, 2.50611752, 2.52982213, 2.27623593,

2.31651678, 2.20127804, 2.37065392, 2.8487936 , 3.04384625])

当你看到散点图上的点之间的间隙时,这又有一定意义:物体拾取速度,在拐角处减速一点,然后再加速回升.

现在,为了找到单位切向量,我们需要对ds_dt进行小的变换,使其大小与velocity的大小相同(这有效地允许我们将向量值函数的速度除以(表示)标量函数ds_dt):

tangent = np.array([1/ds_dt] * 2).transpose() * velocity

这会产生以下numpy数组:

array([[ 1. , 0. ],

[ 0.99681528, -0.07974522],

[ 0.89442719, -0.4472136 ],

[ 0.5881717 , -0.80873608],

[ 0.48685826, -0.87348099],

[ 0.52889289, -0.84868859],

[ 0.55965769, -0.82872388],

[ 0.5922051 , -0.80578727],

[ 0.67747575, -0.73554511],

[ 0.80480291, -0.59354215],

[ 0.90055164, -0.43474907],

[ 0.97796293, -0.2087786 ],

[ 0.99755897, 0.06982913],

[ 0.9486833 , 0.31622777],

[ 0.77979614, 0.62603352],

[ 0.48564293, 0.87415728],

[ 0.03407112, 0.99941941],

[-0.46400699, 0.88583154],

[-0.67572463, 0.73715414],

[-0.73919634, 0.67349 ]])

注意两件事:1.在t的每个值处,切线指向与速度相同的方向,并且2.在t的每个值处,切线是单位矢量.确实:

在[12]中:

In [12]: np.sqrt(tangent[:,0] * tangent[:,0] + tangent[:,1] * tangent[:,1])

Out[12]:

array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,

1., 1., 1., 1., 1., 1., 1.])

现在,由于我们采用切向量的导数并除以其长度来得到单位法向量,我们做同样的技巧(为方便起见,隔离切线的分量):

tangent_x = tangent[:, 0]

tangent_y = tangent[:, 1]

deriv_tangent_x = np.gradient(tangent_x)

deriv_tangent_y = np.gradient(tangent_y)

dT_dt = np.array([ [deriv_tangent_x[i], deriv_tangent_y[i]] for i in range(deriv_tangent_x.size)])

length_dT_dt = np.sqrt(deriv_tangent_x * deriv_tangent_x + deriv_tangent_y * deriv_tangent_y)

normal = np.array([1/length_dT_dt] * 2).transpose() * dT_dt

这为我们提供了以下正常的向量:

array([[-0.03990439, -0.9992035 ],

[-0.22975292, -0.97324899],

[-0.48897562, -0.87229745],

[-0.69107645, -0.72278167],

[-0.8292422 , -0.55888941],

[ 0.85188045, 0.52373629],

[ 0.8278434 , 0.56095927],

[ 0.78434982, 0.62031876],

[ 0.70769355, 0.70651953],

[ 0.59568265, 0.80321988],

[ 0.41039706, 0.91190693],

[ 0.18879684, 0.98201617],

[-0.05568352, 0.99844847],

[-0.36457012, 0.93117594],

[-0.63863584, 0.76950911],

[-0.89417603, 0.44771557],

[-0.99992445, 0.0122923 ],

[-0.93801622, -0.34659137],

[-0.79170904, -0.61089835],

[-0.70603568, -0.70817626]])

请注意,法线向量表示曲线转向的方向.当与散点图一起查看时,上面的向量是有意义的.特别是,在第5点之后,我们从向下转向转向,并且在第12点之后我们开始向左转(相对于x轴).

最后,为了获得加速度的切向和正常分量,我们需要s,x和y相对于t的二阶导数,然后我们可以得到曲率和其余的组件(请记住它们都是t)的标量函数:

d2s_dt2 = np.gradient(ds_dt)

d2x_dt2 = np.gradient(dx_dt)

d2y_dt2 = np.gradient(dy_dt)

curvature = np.abs(d2x_dt2 * dy_dt - dx_dt * d2y_dt2) / (dx_dt * dx_dt + dy_dt * dy_dt)**1.5

t_component = np.array([d2s_dt2] * 2).transpose()

n_component = np.array([curvature * ds_dt * ds_dt] * 2).transpose()

acceleration = t_component * tangent + n_component * normal

你可能感兴趣的:(Python中曲率与弯曲的转换)