3B'de (başlangıç ​​noktası yerine) rastgele bir nokta hakkında nasıl dönebilirim?


15

Ben kuaternionları kullanarak normal şekilde döndürmek istediğim bazı modellerim var, orijini döndürmek yerine, biraz ofset olmasını istiyorum. 3B alanda, bir nokta etrafında döndüğünüzü söylemediğinizi biliyorum; bir eksen etrafında döndüğünü söylüyorsun. Bu yüzden kuyruğunu yerel kökenli olmayan bir vektör etrafında dönen olarak görüyorum.

Render / fizik motorumdaki tüm afin dönüşümler SQT (ölçek, kuaterniyon, çeviri; Oyun Motoru Mimarisi kitabından ödünç alınan bir fikir) kullanılarak saklanır . Bu yüzden bu bileşenlerden her kareyi bir matris oluşturur ve köşe gölgelendiricisine geçiririm. Bu sistemde çeviri uygulanır, ölçeklenir, sonra döndürülür.

Belirli bir durumda, bir nesneyi dünya uzayına çevirmem, ölçeklemem ve nesnenin yerel kökeninde ortalanmayan bir tepe noktası etrafında döndürmem gerekir.

Soru: Mevcut sistemimin yukarıda açıklanan kısıtlamaları göz önüne alındığında, başlangıç ​​noktasından başka bir noktaya odaklanmış bir yerel rotasyonu nasıl elde edebilirim? Sadece matrisleri kullanarak bunu nasıl yapacağınızı açıklayan herkese otomatik olarak oy verin :)


Kuaterniyonlar zaten keyfi bir eksen etrafında bir dönüşü tanımlar; Sahip olduğunuz verilerden böyle bir kuaterniyon oluşturmada sorunlarınız mı var?
Martin Sojka

3
Cidden, cevapları onaylayan insanlar onları gerçekten okuyabilir mi? Bir yöntem, etkili bir formül ve hatta bir gösteri verdim. Oysa tek onaylanan cevap, bazı değerli bilgiler (ve aynı zamanda bazı yanlış bilgiler) sağlarken, bunların hiçbirini içermez ve soruyu bile yanıtlamaz!
sam hocevar

@MartinSojka, bu keyfi bir eksen değil, yaklaşık ve keyfi bir noktadır.
notlesh

@SamHocevar Her iki yanıtınız da yardımcı oldu. Sizinkini seçtim çünkü daha kapsamlıydı ve bir çözüme ulaşmama yardımcı oldu. İkinize de teşekkürler.
notlesh

Ah, özür dilerim - Dual Quaternions ile karıştırdım (bunlar size "ücretsiz" çeviri de sağlıyor). Daha sonra bir cevapta ne demek istediğimi yazacağım; belki de diğerleri, özellikle de üç bileşeninizi sadece biraz daha karmaşık olsa da, bir bileşenine indirgeyebileceğinizden, yararlı olduğunu düşünebilir.
Martin Sojka

Yanıtlar:


17

Kısacası

Sadece SQT formunuzda T'yi değiştirmeniz yeterlidir.

Çeviri vektör değiştirin vile v' = v-invscale(p-invrotate(p))nerede v, ilk çeviri vektörü pEğer rotasyon meydana istediğiniz etrafında noktasıdır ve invrotateve invscalerotasyonunuzdan ve ölçek tersidir.

Hızlı tanıtım

Izin vermek petrafında döndürme nokta olmak r. Izin vermek sölçekleme parametreleri ve vçeviri vektör olmak. Son matris dönüşümü T(p)R(r)T(-p)S(s)T(v)yerine R(r)S(s)T(v).

Ne istediğiniz yeni dönüşüm parametreleri olan v', r've s'nihai matris dönüşümü olacak şekilde R(r')S(s')T(v')ve biz var:

T(p)R(r)T(-p)S(s)T(v) = R(r')S(s')T(v')

Sonsuzluktaki davranış, döndürme parametrelerinin ve ölçekleme parametrelerinin değişemediğini gösterir (bu gösterilebilir). Böylece r = r've var s = s'. Tek eksik parametre bu nedenle v'yeni çeviri vektörünüzdür:

T(p)R(r)T(-p)S(s)T(v) = R(r)S(s)T(v')

Bu matrisler eşitse, tersleri eşittir:

T(-v)S(-s)T(p)R(-r)T(-p) = T(-v')S(-s)R(-r)

Bu özellikle menşe için geçerlidir O:

T(-v)S(-s)T(p)R(-r)T(-p)O = T(-v')S(-s)R(-r)O

Kökeni ölçeklemek ve döndürmek orijini verir, böylece:

T(-v)S(-s)T(p)R(-r)(-p) = -v'

v'dönüşümünüzü SQT formunda saklamanızı sağlayan yeni çeviri vektörüdür. Muhtemelen hesaplamayı basitleştirmek mümkündür; ancak en azından gerekli depolama alanı artırılmaz.


Açıklama için teşekkürler. BTW, SQT temsil hileleri hakkında daha fazla bilgi alabileceğim herhangi bir kaynak biliyor musunuz?
pachanga

Yanılıyorsam beni düzeltin, ancak başka bir çözüm Quaternion'unuzu normal olarak saklamak gibi görünüyor ve keyfi bir nokta / eksen etrafındaki çeviriyi hesaba katmanız gerekiyorsa, Q matrisini bununla birlikte oluşturun, çeviri vektörünü çıkarın Bu matristen (genellikle son sütunda) ve bunu Çeviri vektörü nesnelerine ekleyin, ardından geçici matrisinizi dışarı atın.
johnbakers

15

Rotasyon matrislerinizi türetmek için kullanılan tüm kanonik rotasyonel formüller, başlangıç ​​noktası etrafında rotasyon içindir. Bu dönüşü belirli bir noktaya uygulamak istiyorsanız, önce başlangıç ​​noktasını dengelemeniz - ya da eşdeğer olarak, etrafında döndürmek istediğiniz nokta başlangıç ​​noktasında olacak şekilde nesneyi hareket ettirmeniz gerekir.

Önce 2D durumu düşünün, çünkü daha basittir ve teknik ölçeklendirir. Kökeni merkez alan 2 genişliğinde bir küpünüz varsa ve merkeziyle yaklaşık 45 derece döndürmek istiyorsanız, bu 2D döndürme matrisinin önemsiz bir uygulaması olacaktır .

Ancak bunun yerine, sağ üst köşesinde (konumunda bulunur 1,1) döndürmek isterseniz, önce köşeyi başlangıç ​​noktasında olacak şekilde çevirmeniz gerekir. Bu bir çeviri ile gerçekleştirilebilir -1,-1. Sonra nesneyi daha önce olduğu gibi döndürebilirsiniz, ancak bunu geri çevirerek takip etmeniz gerekir 1,1. Yani genel olarak, yaklaşık noktanın Rdönmesi için dönme matrisine ulaşmak için :rP

R = translate(-P) * rotate(r) * translate(P)

nerede translateve rotatekanonik çeviri / rotasyon matrisleridir. Olduğu gibi, bu da rotasyona bir eksen sağlamak zorunda kalmadan istisnai olarak 3D'ye ölçeklenir - her zaman kanonik X, Y veya Z ekseni rotasyon matrislerini her zaman seçebilirsiniz, ancak bu donuk olurdu. Rasgele eksen açısı döndürme matrisini kullanmak isteyeceksiniz . R3D finaliniz şu şekilde:

R = translate(-P) * rotate(a,r) * translate(P)

burada adönme eksenini temsil eden bir birim vektördür ve Pşimdi model alanında dönme noktasını temsil eden bir 3B noktadır.

O sırada da, kuaterniyonlar dönüştürülen olabilir için ve gelen Eğer yolu yani başlığı senin birleştirme yapabileceği şekilde, matris temsilleri. Ya da her şeyi matris olarak bırakabilirsiniz (kuaterniyonların aklı başında bir şekilde enterpolasyon yapmak daha kolay, ancak ihtiyacınız olup olmadığı size kalmış gibi bazı güzel avantajlara sahiptir).

Ayrıca:

Bu yüzden kuyruğunu yerel kökenli olmayan bir vektör etrafında dönen olarak görüyorum.

Kesin olarak konuşmak gerekirse, vektörler pozisyonları bir başlangıç ​​noktasının yer değiştirmeleri olarak düşünerek temsil etmek için kullanılabilirken, vektörlerin pozisyonları yoktur, bu yüzden birini görselleştirmek biraz alışılmadık bir durumdur.


Teşekkürler, bu iyi bir cevap. Yine de sistemimin kısıtlamalarına uymuyor. "Bu kısıtlamalar göz önüne alındığında bu mümkün mü?" Afin dönüşümlerin bir temsili olarak SQT kullanımının kaçınılmaz bir eksikliği mi?
notlesh

Kısıtlamalarınıza mükemmel uyum sağlar. R matrisi (translate-rotate-translate-back olarak üretilir) rotasyon matrisinizdir. "SQT" sisteminizdeki Q'yu R ile değiştirin, böylece daha yaygın olan ölçekle döndürme-çevirme paradigmasına sahip olursunuz ve işiniz bitmiştir. Bu son tercüme, istenen dönüşü üretmek için yapılan iki ara çeviriden bağımsızdır.

Kuaterniyonu bir matrisle değiştirmemi mi öneriyorsun? Bu, nesne başına 12 bayt daha (4x3 matris olarak saklarsam 8)! Yine de içimdeki iyimserleri susturup buna bir koşuşturma getireceğim. (Bu aslında ayak izinde 2 kb'lik bir artışa bile neden olmayacaktır ...) Yanıtlarınız için teşekkürler.
notlesh

Ayrıca, aralarında dönüş yapabilir, dönüş kuaterniyonunu bu şekilde oluşturabilir ve mevcut sisteminize tekrar takabilirsiniz.

1
SamHocevar: Alternatif olarak, bunların herhangi bir kombinasyonu tek bir vida olarak ifade edilebilir .
Martin Sojka
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.