2009-04-18 13 views
8

Rysuję płaski dysk za pomocą gluDisk() w mojej scenie. gluDisk() rysuje dysk skierowany w stronę dodatniej osi Z, ale chcę, aby był skierowany w stronę jakiejś arbitralnej normalności, którą mam.
Najwyraźniej muszę użyć glRotate(), aby uzyskać właściwy widok dysku, ale jaki powinien być obrót? Pamiętam, że można to obliczyć za pomocą Quaternions, ale nie mogę sobie przypomnieć matematyki.Czwartorzędowa matematyka do rotacji?

Odpowiedz

16

Rozwiązanie powinno być proste i nie powinno wymagać czworaka.

Oś obrotu, aby uzyskać wartość od Normal1 do Normal2, musi być ortogonalna dla obu, więc po prostu weź ich wektor krzyżowy .

Ilość obrotów jest łatwo ustalana na podstawie ich produktu dot-product. Ta wartość to | A |. | B | .cos (theta), ale ponieważ dwa normalne wektory powinny być znormalizowane, da to cos (theta), więc po prostu weź odwrotny cosinus, aby uzyskać wielkość obrotu.

Wynikowy wektor i kąt są wymaganymi parametrami dla glRotate() - nie ma potrzeby samodzielnego obliczania rzeczywistej macierzy obrotu.

p.s. nie zapominaj, że glRotate() potrzebuje kąta w stopniach, ale normalne funkcje wyzwalania C działają w radianach.

+0

Dziękuję. to działało idealnie. – shoosh

3

W czwartorzędach opisano obrót wokół osi. <w,x,y,z> obróci się wokół osi <x,y,z> w zależności od równowagi między wartością w a wielkością wektora.

<cos θ/2, x*sin θ/2, y*sin θ/2, z*sin θ/2>, where |<x, y, z>| = 1 

Na przykład, obraca się zmierzyć dodatni osi Y, a nie trzeba obracać o 90 ° wokół osi X. Wektor miałby być <0, 1, 0>, a kwaternion byłby <cos 90°, 0, sin 90°, 0> = <0, 0, 1, 0>.

Aby obrócić figurę w kierunku dodatniej osi Z, w stronę wektora <x,y,z> należy znaleźć wektor obrotu i kąt obrotu. Aby znaleźć oś obrotu, możesz wziąć produkt równoległy do ​​bieżącego wektora i tam, gdzie chcesz go mieć.

Jeśli jest skierowana w kierunku dodatniej osi Z, bieżącym wektorem będzie <0, 0, 1>. Jeśli chcesz zmierzyć się z <x,y,z>, osią obrotu będzie <0, 0, 1> x <x, y, z> = <-y, x, 0>, a kąt będzie wynosił arctan(sqrt(x^2+y^2),z). Kwaternion się

<cos(θ/2), -y*sin(θ/2), x*sin(θ/2), 0>, where θ = arctan(sqrt(x^2+y^2), z) 
6

obrót wokół dowolnej osi: zadanym kątem R, w radianach, a jednostkowe wektora u = ai + bj + ck lub [a, b, c], określenie:

q0 = cos(r/2) 
q1 = sin(r/2) a 
q2 = sin(r/2) b 
q3 = sin(r/2) c 

i zbudować z tych wartości macierzy rotacji:

(q0^2+q1^2 - q2^2 - q3^2 | 2*(q1*q2 - q0*q3)   | 2*(q1*q3 + q0*q2)  ) 
Q =(2*(q2*q1 + q0*q3)  | (q0^2 - q1^2 + q2^2 - q3^2) | 2*(q2*q3 - q0*q1)  ) 
    (2*(q3*q1 - q0*q2)  | 2*(q3*q2 + q0*q1)   | q0^2 - q1^2 - q2^2 + q3^2) 

aby znaleźć rotację trzeba zrobić, można obliczyć iloczyn między aktualnym wektorem i wektorem docelowym. Otrzymasz ortogonalny wektor (który będzie twoim rotacyjnym wektorem, by utworzyć kwaternion), a długość tego wektora jest sinem kąta, który musisz zrekompensować, aby wektor początkowy i docelowy zachodziły na siebie.

Powiązane problemy