2015-02-01 5 views
7

특수 카메라를 사용하여 1 초 간격으로 x, y 좌표 (cm)를 측정했습니다. 나는 NumPy와 배열에있는 데이터를 가지고 :커브 곡률 (numpy)

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 ]]) 

그리고 곡선은 다음과 같습니다

plt.scatter(a[:,0], a[:,1]) 

enter image description here

질문 : 접선 계산할 수있는 방법

및 각 점에서의 반경 방향 가속 벡터?

enter image description here

내가 쉽게 np.diff(a, axis=0)vxvy 전망을 계산할 수 있어요하지만 난 NumPy와/파이썬 멍청한 놈과 계속 내 머리 방법입니다 : 내가 관련이있을 수있는 몇 가지 공식을 발견했다. 각 점의 곡률을 계산할 수 있다면 문제도 해결 될 것입니다. 누군가 도울 수 있습니까?

+1

글쎄, 당신은 바꿔야합니다는, 예를 들어' (델타 x)/(델타 t)'(SO가 LaTeX를 지원하지 않기 때문에 조잡한 수학 표기법을 용인하십시오). 간격은 모두 1 초 간격이므로 '델타 t'는 1이므로 'x'를 델타 x로 바꾸고 y를 마찬가지로 쓸 수 있습니다. 이것은 근사치 일 것입니다. 그러나 곡선 피팅을 시도하지 않는 한, 여러분이 가지고있는 데이터 셋으로 할 수있는 최선의 방법입니다. –

+0

죄송합니다. 죄송합니다. 제 응답은 너무 오래되었습니다. 다행히도 여전히 도움이됩니다. –

답변

22

EDIT : 나는이 답변을 몇 시간 동안 정리해 두었으므로 최신 편집 내용을 놓쳐 곡면 만 필요하다는 것을 알 수 없었습니다. 바라건대,이 대답은 상관없이 도움이 될 것입니다.

커브 피팅을 수행하는 것 외에는 미분을 근사하는 방법은 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)]) 

이것은에 대해 다음 벡터를 제공합니다.:

a의 산점도에서이기는 경우 의미가
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/dtdy/dt과 같습니다.따라서, 우리는 하나 개의 초 시간 간격의 각각에서 값 numpy 배열로 ds_dt를 나타내는 것이며, 각 값은 각 초 속도의 근사치에 해당 :

:

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]) 

a의 산점도에있는 점들 사이의 틈을 보면 약간의 의미가 있습니다. 개체가 속도를 높이고 모서리를 감안하여 속도를 줄인 다음 다시 속도를 높입니다. 그 크기가이 효과적으로하여 벡터 함수 velocity를 나눌 수있게 해준다 (velocity의 경우와 동일하도록

이제, 단위 접선 벡터를 찾기 위해, 우리는 ds_dt에 작은 변화를 만들 필요가 (표현) 스칼라 함수는 ds_dt) : 012의 각 값 1.

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 ]]) 

두 가지 주 :

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

이는 다음 numpy 어레이를 얻을, tangentvelocity과 같은 방향을 가리키며, 2는 t의 각 값에서 tangent은 단위 벡터입니다. 실제로 :

는 [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)의 :

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]]) 
0 :

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 

이 우리에게 normal에 대한 다음과 같은 벡터를 제공합니다

법선 벡터는 곡선이 선회하는 방향을 나타냅니다. 위의 벡터는 a의 산점도와 함께 볼 때 의미가 있습니다. 특히, 우리는 다섯 번째 지점 이후로 돌아서기로 돌기부터 시작하여 12 번째 지점 이후에 (x 축에 대해) 왼쪽으로 돌기 시작합니다.

마지막으로, 가속도의 접선 및 일반 부품을 얻기 위해, 우리는 t에 대한 s, xy의 두 번째 파생 상품을 필요로하고 우리는 곡률과 우리의 나머지 구성 요소는 (염두에두고 얻을 수 있습니다 그들은 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 
+0

네, 매우 도움이됩니다! 고마워. – Elian

+0

당신은 더 이상 환영합니다. :) –

+1

커뮤니티 @ 잭 마니를 도와 주신 것에 대해 감사드립니다! – Olshansk