我想創建一個簡單的物理系統在Python中的作品quaternions
與velocity/position
類似的方式。它的主要目標是模擬一個被拖動的對象,並隨着時間的推移嘗試追趕另一個對象。模擬使用3個變量:k
:彈簧常數,d
:衰減係數,以及m
:被拖動物體的質量。春季物理應用於四元數使用python
採用經典的歐拉積分,我可以解決的立場:
import numpy as np
from numpy.core.umath_tests import inner1d
# init simulation values
dt = 1./30. # delta t @ 30fps
k = 0.5 # Spring constant
d = 0.1 # Damping
m = 0.1 # Mass
p_ = np.array([0,0,0]) # initial position of the dragged object
p = np.array([1,2,0]) # position to catch up to, in real life this value could change over time
v = np.array([0,0,0]) # velocity buffer (init speed is assumed to be 0)
# Euler Integration
n = 200 # loop over 200 times just to see the values converge
for i in xrange(n):
x = (p-p_)
F = (k*x - d*v)/m # spring force
v = v + F * dt # update velocity
p_ = p_ + v * dt # update dragged position
print p_ # values oscillate and eventually stabilize to p
這對於位置的偉大工程。通過改變k
,d
和m
我可以得到一個迅捷/重結果和總體來說,我很滿意我的感覺:
現在我想做同樣的事情quaternions
。因爲我沒有使用quaternions
進行物理學的經驗,所以我沿着天真的道路前進,並應用相同的功能進行了一些修改,以處理quaternion
翻轉和歸一化。
# quaternion expressed as x,y,z,w
q_ = np.array([0., 0., 0., 1.]) # initial quaternion of the dragged object
q = np.array([0.382683, 0., 0., 0.92388]) # quaternion to catch up to (equivalent to xyz euler rotation of 45,0,0 degrees)
v = np.array([0.,0.,0.,0.]) # angular velocity buffer (init speed is assumed to be 0)
# Euler Intration
n = 200
for i in xrange(n):
# In a real life use case, q varies over time and q_ tries to catch up to it.
# Test to see if q and q_ are flipped with a dot product (innder1d).
# If so, negate q
if inner1d(q,q_) < 0:
q = np.negative(q)
x = (q-q_)
F = (k*x - d*v)/m # spring force
v = v + F * dt # update velocity
q_ = q_ + v * dt # update dragged quaternion
q_ /= inner1d(q_,q_) # normalize
print q_ # values oscillate and eventually stabilize to q
而令我非常驚喜的是,它給了我非常不錯的結果!
因爲我有我的直覺去了,我相信我的解決方法是有缺陷的(例如,如果Q和Q_相向),並且有一個正確的/更好的方法來達到我想要的。
問題:
什麼是模擬在quaternions
彈簧力的正確途徑,考慮到(至少)拖動對象的mass
,彈簧stiffness
和damping factor
。
實際的Python代碼將不勝感激,因爲我讀博士論文非常困難:)。對於quaternion
操作,我通常會參考Christoph Gohlke's excellent library,但請隨時在答案中使用其他人。
我懷疑你在使用numpy四元數的時候比我們大多數人都領先。 – hpaulj
我不知道如何正確查找'v',但'x'應該可能與[multiplicative inverse](https://stackoverflow.com/a/22167097/320036)一起找到,並且'q_'應該可能請使用[Slerp](https://en.wikipedia.org/wiki/Slerp#Quaternion_Slerp)。 – z0r