web-gelistirme-sc.com

Kuaterniyon ve normalleşme

Bir vektörü döndürmek istersem kuaternyonların normalleştirilmesi gerektiğini biliyorum.

Fakat bir kuaterniyonu otomatik olarak normalleştirmemek için herhangi bir sebep var mı? Ve varsa, hangi kuaterniyon işlemleri normalize edilmemiş kuaterniyonlara neden olur?

  • İki kuaterniyonun çarpılması?
  • Nokta ürün?

Üzgünüm, bu soru biraz bulanıksa. Hala kafamı kuaterniyonların etrafına sarmaya çalışıyorum.

16

Bir kuaterniyon üreten herhangi bir işlemin normalize edilmesi gerekir, çünkü kayan nokta oluşma hataları, ünite uzunluğunun olmamasına neden olur.

Performans nedenleriyle otomatik olarak normalleştirme yapan standart rutinlere karşı tavsiyelerde bulunabilirim. Herhangi bir yetkili programcı, hassas sorunların farkında olmalı ve gerektiğinde miktarları normalleştirebilmelidir - ve birim uzunluk kuaterniyonuna sahip olmak her zaman gerekli değildir.

Aynısı vektör işlemleri için de geçerlidir.

8
user1157123

Geç cevap; Bu cevap, sorgulayıcı için değil, gelecekte bu soruya rastlayan kişiler içindir.

Sadece bir kuaterniyonu nadiren normalleştirmekle ilgili diğer iki cevaba katılmıyorum. Bir vektörü döndürmek/dönüştürmek için bir kuaterniyon kullanmak veya kuaterniyonun örtük olarak varsaydığını varsaymak için bir dönme/dönüşüm matrisi oluşturmak için standart formüller normalleştirilmiştir. Normal olmayan bir kuaterniyon kullanılmasından kaynaklanan hatalar kuaterniyonun büyüklüğünün karesiyle orantılıdır. Kuadratik hata büyümesi en iyi kaçınılması gereken bir şeydir.

Sık sık normalleşirseniz, kareköke ihtiyacınız yoktur. Birinci dereceden bir yaklaşım oldukça iyi çalışıyor. İşte IEEE iki katına çıktıkça kuaterniyonlar için kullanıyorum, stilize:

double qmagsq = quat.square_magnitude();
if (std::abs(1.0 - qmagsq) < 2.107342e-08) {
    quat.scale (2.0 / (1.0 + qmagsq));
}
else {
    quat.scale (1.0 / std::sqrt(qmagsq));
}

Unutmayın ki, 2.0/(1.0+qmagsq) değerini tahmin etmek için ilk sipariş Taylor genişleme 0.5*(3.0-qmagsq) yerine, birinci dereceden Padé yaklaşım 1.0/std::sqrt(qmagsq) kullanıyorum. Bu yaklaşım, eğer geçerliyse, karekök çağrısını basit bir bölmeyle değiştirir. Anahtar, bu yaklaşımın ne zaman geçerli olduğunu bulmaktır, bu da 2.107342e-08 sihirli sayısının devreye girdiği yerdir.

Neden bir Padé yaklaşımı? İki sebep. Birincisi, qmagsq değerinin bire yakın değerleri için 1+qmagsq, 3-qmagsq işlevinden daha az hassasiyet kaybeder. Diğeri ise Padé yaklaşımının hatayı Taylor genişlemesine kıyasla üç kat azalttığıdır. 0 ve 2 arasındaki qmagsq değerleri için, bu yaklaşımdaki hata (1-qmagsq)^2 / 8 'dan küçüktür. Sihirli sayı 2.107342e-08, bu hatanın IEEE için bir ULP'nin iki katından daha fazla olduğunu gösterir. Makul küçük adımlar atıyorsanız, kuaterniyonun büyüklüğünün karesi her zaman bu sınır dahilinde olacaktır. Asla sqrt'yi aramayacaksınız.

Bu "her zaman normalleş" paradigmasının tek istisnası, kuaterniyonları yaymak için Lie grubu entegrasyon tekniği kullanıyorsanız olabilir. Bunun ne anlama geldiğini bilmiyorsanız, muhtemelen bir kuaterniyonu yaymak için q(t+Δt) = q(t) + dq(t)/dt*Δt eşdeğerini kullanıyorsunuzdur. Lie grubu entegratörü olmayan yüksek dereceli bir entegrasyon tekniği kullanıyor olsanız bile, hala bu Euler adımını kullanıyorsunuz.

27
David Hammen

Yeterince komik, rotasyon matrisleri oluşturmak, kuaternyonların normalleştirilmesinin gerekli olmadığı ve size bir tane kazandıran bir işlem. sqrtname__:

M = [w*w+x*x-y*y-z*z, 2*(-w*z+x*y),    2*(w*y+x*z);
     2*(w*z+x*y),     w*w-x*x+y*y-z*z, 2*(-w*x+y*z);
     2*(-w*y+x*z),    2*(w*x+y*z),     w*w-x*x-y*y+z*z] / (w*w+x*x+y*y+z*z)

(bir MATLAB-ish notasyonunda) kuaterniyon w+x*i+y*j+z*k için.

Dahası, homojen koordinatlarla ve 4x4 dönüşüm matrisleriyle çalışıyorsanız, bazı bölme işlemlerini de kaydedebilirsiniz: kuaterniyon normalize edilmiş gibi 3x3'lük bir döndürme kısmı yapın ve kare uzunluğunu (4,4) öğesinin içine koyun :

M = [w*w+x*x-y*y-z*z, 2*(-w*z+x*y),    2*(w*y+x*z),     0;
     2*(w*z+x*y),     w*w-x*x+y*y-z*z, 2*(-w*x+y*z),    0;
     2*(-w*y+x*z),    2*(w*x+y*z),     w*w-x*x-y*y+z*z, 0;
     0,               0,               0,               w*w+x*x+y*y+z*z].

Tam bir dönüşüm için her zaman olduğu gibi bir çeviri matrisi vb. İle çarpın. Bu şekilde yapabilirsiniz, ör.

[xh yh zh wh]' = ... * OtherM * M * [xold yold zold 1]';
[xnew ynew znew] = [xh yh zh] / wh.

Elbette ki kuaternyonları normalleştirme hala tavsiye edilir (başka işlemler için de gerekli olabilir).

5
vpozdyayev

Bir ünite kuaterniyonu, ilk kez türevini sayısal olarak entegre ederek elde edilirse, entegratör basit bir hata geri bildirimi kullanarak otomatik olarak normalleştirebilir.

q kuaterniyonların 4'e 1 sütunluk bir matrisini ve dq zaman türevini temsil etsin. Sonra dq + 0.5 (1-qq) q/tau yerine dq yerine entegratöre gönderilmesi ve uygun bir zaman sabiti kullanılması tau sürekli normalleşecektir q . q.q iç ürünü temsil eder.

Yerçekimsiz alanda yüzen 3.6 milyon saniye boyunca muhafazakar, eklemli bir Bricard mekanizmasını simüle ettim, yaklaşık 42 gün. Kuaterniyonlar, kayan taban gövdesinin yönelimini temsil ediyordu. Toplam enerji, 0,5 saniyelik bir zaman sabiti tau kullanarak, milyonda bir kısımda sabit kaldı. Sayısal bütünleştirici DE'de, 10 ^ -12 mutlak hata toleransı ve sıfırın nispi hata toleransı kullanılmıştır.

http://www.Amazon.com/Bilgisayar-Solution-Ordinary-Differential-Equations/dp/0716704617/

Kuaterniyonlar genellikle sayısal entegrasyonla elde edilir. Bütünleştirici içinde normalleştirilmezlerse, büyüklük ve faz hataları birikir. Normalleştirilmiş bir kuaterniyon, bir birim küresi boyunca hareket eder ve ilk kez türevi o küreye teğet olur. Kuaterniyon ünite küresinden uzaklaşırsa, entegratörün dışında normalleşmenin düzeltemeyeceği faz hataları birikmeye başlar. Bu yüzden, kuaterniyon, faz hatalarını en aza indirmek için sayısal entegratör içinde sürekli normalleştirilmelidir.

2
Roger Wehage

sorunuz çok kesin fakat bir kuaterniyonu normalize etmeniz gerekiyorsa basit

q_normalized = q/kare (norm (q))

ile, q = q1 + q2i + q3 j + q4 k norm (q) = (q1) ^ 2 + (q2) ^ 2 + (q3) ^ 2) + (q4) ^ 4

başka bana sorunuzu açıklarsanız

0