Czytam książkę online „Uczenie się nowoczesnego programowania grafiki 3D” Jasona L. McKessona
Na razie mam problem z blokadą gimbala i jak go rozwiązać za pomocą czwartorzędów.
Jednak tutaj, na stronie Quaternions .
Częściowym problemem jest to, że próbujemy zapisać orientację jako serię 3 skumulowanych obrotów osiowych. Orientacje to orientacje, a nie rotacje. A orientacje z pewnością nie są serią obrotów. Musimy więc traktować orientację statku jako orientację, jako określoną ilość.
Wydaje mi się, że to pierwsze miejsce, w którym zaczynam się mylić. Powodem jest to, że nie widzę dramatycznej różnicy między orientacjami a obrotami. Nie rozumiem też, dlaczego orientacja nie może być reprezentowana przez serię obrotów ...
Również:
Pierwszą myślą w tym celu byłoby zachowanie orientacji jako matrycy. Kiedy nadchodzi czas na modyfikację orientacji, po prostu stosujemy transformację do tej macierzy, zapisując wynik jako nową bieżącą orientację.
Oznacza to, że każde odchylenie, skok i przechylenie zastosowane do bieżącej orientacji będzie względem tej bieżącej orientacji. Właśnie tego potrzebujemy. Jeśli użytkownik zastosuje odchylenie dodatnie, chcesz, aby odchylenie obracało je względem miejsca, w którym są obecnie skierowane, a nie względem jakiegoś stałego układu współrzędnych.
Rozumiem pojęcie, ale nie rozumiem, w jaki sposób, jeśli akumulacja transformacji macierzowych jest rozwiązaniem tego problemu, w jaki sposób kod podany na poprzedniej stronie to nie tylko to.
Oto kod:
void display()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutil::MatrixStack currMatrix;
currMatrix.Translate(glm::vec3(0.0f, 0.0f, -200.0f));
currMatrix.RotateX(g_angles.fAngleX);
DrawGimbal(currMatrix, GIMBAL_X_AXIS, glm::vec4(0.4f, 0.4f, 1.0f, 1.0f));
currMatrix.RotateY(g_angles.fAngleY);
DrawGimbal(currMatrix, GIMBAL_Y_AXIS, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f));
currMatrix.RotateZ(g_angles.fAngleZ);
DrawGimbal(currMatrix, GIMBAL_Z_AXIS, glm::vec4(1.0f, 0.3f, 0.3f, 1.0f));
glUseProgram(theProgram);
currMatrix.Scale(3.0, 3.0, 3.0);
currMatrix.RotateX(-90);
//Set the base color for this object.
glUniform4f(baseColorUnif, 1.0, 1.0, 1.0, 1.0);
glUniformMatrix4fv(modelToCameraMatrixUnif, 1, GL_FALSE, glm::value_ptr(currMatrix.Top()));
g_pObject->Render("tint");
glUseProgram(0);
glutSwapBuffers();
}
Według mnie, to, co robi (modyfikując macierz na stosie), nie rozważa akumulacji macierzy, ponieważ autor połączył wszystkie indywidualne transformacje obrotu w jedną macierz, która jest przechowywana na górze stosu.
Rozumiem, że macierz polega na tym, że są one używane do ustalenia punktu względem początku (powiedzmy ... modelu) i uczynienia go względem innego początku (kamery). Jestem pewien, że jest to bezpieczna definicja, ale wydaje mi się, że brakuje czegoś, co blokuje mi zrozumienie problemu blokady gimbala.
Jedną rzeczą, która nie ma dla mnie sensu jest: jeśli macierz określa różnicę względną między dwiema „spacjami”, to dlaczego obrót wokół osi Y dla, powiedzmy, toczenia, nie umieszcza punktu w „przestrzeni toczenia” „które można następnie przekształcić jeszcze raz w stosunku do tego rzutu ... Innymi słowy, żadne dalsze przekształcenia do tego punktu nie powinny dotyczyć tej nowej„ przestrzeni rzutu ”, a zatem nie powinny mieć obrotu względem poprzedniego” model area ”, co powoduje blokadę kardanową.
Właśnie dlatego występuje blokada gimbala, prawda? Wynika to z faktu, że obracamy obiekt wokół osi X, Y i Z, zamiast obracać obiekt wokół własnych osi względnych . A może się mylę?
Ponieważ najwyraźniej ten kod, który podłączyłem, nie jest kumulacją transformacji macierzy, możesz podać przykład rozwiązania wykorzystującego tę metodę.
Podsumowując:
- Jaka jest różnica między obrotem a orientacją?
- Dlaczego kod nie jest powiązany z przykładem akumulacji transformacji macierzowych?
- Jaki jest prawdziwy, konkretny cel matrycy, jeśli źle ją popełniłem?
- Jak można rozwiązać problem blokady gimbala za pomocą akumulacji transformacji macierzowych?
- Dodatkowo, jako bonus: dlaczego przekształcenia po obrocie są nadal względem „obszaru modelu”?
- Kolejna premia: czy mylę się przy założeniu, że po transformacji nastąpią dalsze transformacje w stosunku do prądu?
Ponadto, jeśli nie zostało to dorozumiane, używam OpenGL, GLSL, C ++ i GLM, więc przykłady i objaśnienia w odniesieniu do nich są bardzo mile widziane, jeśli nie są konieczne.
Im więcej szczegółów, tym lepiej!
Z góry dziękuję.
źródło
Nagromadzenie macierzy może w rzeczywistości rozwiązać blokadę gimbala. Gromadząc obroty, dodajesz kardana, umożliwiając dowolną rotację. Schemat dostarczony przez ktodisco pokazuje blokadę gimbala na lewym schemacie. Macierz dla tej orientacji można zdefiniować jako:
Z powodu rotacji gimbala y gimbale X i Z są teraz zablokowane, więc straciliśmy jeden stopień ruchu. W tym momencie nie mamy ziewania (lokalne y, globalne z) za pomocą tych trzech kardanowych. Ale dodając kolejny gimbal, mogę obracać się lokalnie wokół y:
Dla każdego nowego rzutu, skoku i odchylenia po prostu dodaj kolejny gimbal, Kumulując je w jedną matrycę. Tak więc za każdym razem, gdy potrzebny jest kolejny obrót lokalny, tworzony jest obrót i mnożony do macierzy akumulacji. Jak wspomniano w rozdziale, nadal występują problemy, ale blokada gimbala nie jest jedną z nich.
źródło