2015-02-01 41 views
7

1 sn sabit zaman aralıklarında özel bir fotoğraf makinesine sahip bir nesnenin x, y koordinatlarını (cm cinsinden) ölçüyorum. Ben numpy dizide veri var:Sayısal eğri eğri

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

Ve eğri şuna benzer:

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

enter image description here

Soru: teğet nasıl hesaplayabilir

ve her noktada radyal hızlanma vektörleri?

enter image description here

Kolayca np.diff(a, axis=0) ile vx ve vy projeksiyonları hesaplamak mümkün ama ben numpy/piton çaylak değilim ve bunu devam başımın üzerinde yoludur: Ben Alakalı olabilecek formüller bulundu. Her noktada eğriliği hesaplayabilirsem, benim de sorunum çözülecekti. Biri yardım edebilir mi?

+1

Eh, değiştirmek gerekecek, örneğin ' x (X)/(Delta x)/(Delta t) ile (SO, LaTeX'i desteklemediği için ham matematik notasyonunu affet). Aralıklarınız bir saniyelik aralık olduğu için, 'Delta t' 1'dir, bu yüzden 'x' yerine 'x' ve 'x' ile değiştirebilirsiniz. Elbette, bunlar yaklaşık bir yaklaşım olacaktır, ancak bir eğri uydurma girişiminde bulunmazsanız, sahip olduğunuz veri kümesiyle yapabileceğiniz en iyisi budur. –

+0

Oops, üzgünüm, cevabım biraz fazla uzun-sarmalı, şimdi sadece eğriliğin peşindesin. Umarım hala yardımcı olur. –

cevap

22

DÜZENLEME: bu iş dolayısıyla cevaplamak ve ilgili birkaç saat boyunca araya yüzden sadece eğrilik ihtiyacı olduğunu belirten son düzenlemeler kaçırdı. Umarım, bu cevap işe yaramaz.

Bazı eğri uydurma yapmaktan başka, türevlerimize yaklaşım yöntemimiz finite differences aracılığıyladır. Neyse ki, numpy Şimdi her iç noktası için önceki ve sonraki yamaçları ortalama ve yalnız her son nokta bırakmanın ayrıntılarını dikkat çekici, bizim için bu fark hesaplamaları yapan bir gradient yöntemi vb

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

var, biz hesaplamak her değişkenin türevleri ve onları bir araya getirin (bazı nedenlerle, eğer biz sadece np.gradient(a) diye adlandırırsak, dizilerin bir listesini alırız ... kafamın üstünden ne olup bittiğine emin değilim, ama sadece etrafta çalışacağım şimdi):

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

Bu bizeiçin aşağıdaki vektör verir:

a ait ScatterPlot bakarak zaman mantıklı
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 ]]) 

.

Şimdi hız için, hız vektörünün uzunluğunu alıyoruz. Ancak, burada aklımızda tuttuğumuz bir şey var: her şey t'un bir fonksiyonudur. Bu nedenle, ds/dt, t'un (t'un bir vektör fonksiyonunun aksine) bir skaler işlevidir, tıpkı dx/dt ve dy/dt gibi.Böylece, bir ikinci zaman aralıklarının her birinde bir değerler numpy dizisi olarak ds_dt temsil edecek, her bir değer her bir ikinci hızın yaklaşık bir tekabül eden

:

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

Bu, aşağıdaki diziyi vermektedir Eğer a ait ScatterPlot noktalar arasındaki boşluklar bakmak gibi yine bazı mantıklı

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

: daha da geri hızlandırır sonra korneri ve aynı nesne biraz yavaşlıyor, hızlanıyor. onun büyüklüğü bu etkili tarafından vektör değerli fonksiyon velocity bölmek bize verir (velocity aynıdır, böylece

Şimdi, birim teğet vektör bulmak için, biz ds_dt için küçük bir dönüşüm yapmak gerekir (temsili) skalar fonksiyonu ds_dt): 012 her bir değeri de: 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 ]]) 

Not iki şey:

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

Bu, aşağıdaki numpy dizi elde edilir, tangent, velocity ve 2. ile aynı yönde işaret ediyor. t'un her bir değerinde, tangent bir birim vektörüdür. Nitekim:

[12] 'de

: Artık

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

biz birim normal vektörü elde etmek için uzunluğu ile teğet vektör ve bölünmenin türevini almak için, aynı hile (komponentleri izole kolaylık için tangent) ait:

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 

Bu bize normal için aşağıdaki vektör verir

Normal vektörün, eğrinin dönme yönünü temsil ettiğini unutmayın. Yukarıdaki vektör a için scatterplot ile birlikte görüntülendiğinde anlamlıdır. Özellikle, beşinci noktadan sonra dönüşe geçmekten dönüyoruz ve 12. noktadan sonra sola (x eksenine göre) dönmeye başlıyoruz.

Son olarak, ivme teğet ve normal bileşenleri almak için, biz t göre s, x ve y ikinci türevleri, ve sonra biz eğrilik ve bileşenlerinin geri kalanı (göz önünde tutarak alabilirsiniz onlar t tüm skaler fonksiyonlar) olduğu: Eğer Yaptığın inanmıyorum eğri için parametrik denklemler() güzel bir sisteme sahip olmadıkça

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

Evet, çok yardımcı oluyor! Çok teşekkürler. – Elian

+0

Bir şey değil. :) –

+1

Topluluğa yardım ettiğin için çok teşekkürler @JackManey! – Olshansk