Grafika 3D
 
  Zarejestruj się
::  Newsy  ::  Pliki  ::  Twoje Konto  ::  Forum  ::
Menu
· Strona główna
· Forum
· Linki
· Lista u?ytkowników
· O nas...
· Pliki
· Statystyki
· Twoje Konto
Tutoriale
· API
· Matematyka
· Teoria
· Direct3D
· OpenGL
· Techniki
Kto Jest Online
Aktualnie jest 38 gość(ci) i 0 użytkownik(ów) online.

Jesteś anonimowym użytkownikiem. Możesz się zarejestrować za darmo klikając tutaj
Tutoriale - Matematyka - Transformacje

Znamy już właściwości wektorów i posiadamy podstawowe informacje o operacjach na macierzach. Czas więc się dowiedzieć jak to wszystko zastosować w grafice 3D. Z wektorami raczej poradzimy sobie łatwo. Będziemy ich używać do liczenia odległości pomiędzy punktami, do wyznaczania kierunku, do określania punktów w przestrzeni. Co innego macierze. Z nimi będziemy mieć o wiele więcej zabawy no a zastosowanie ich w manewrowaniu obiektami na płaszczyźnie czy w przestrzeni wszystko znacznie nam ułatwi. Powiedzmy sobie zatem o przekształceniach w grafice. Zacznijmy naszą zabawę może nie od 3D, ale od starego poczciwego 2D. Większość z was zapewne zna doskonale podstawowe przekształcenia jakie możemy zastosować na naszych obiektach, ale dla porządku i dla nie kumatych przypomnijmy je sobie właśnie teraz.
  • Przesunięcie
Załóżmy sobie, że mamy jakiś obiekt na płaszczyźnie zdefiniowany za pomocą kilku punktów. I nagle mamy taką chęć, żeby sobie ten obiekt na przykład przesunąć. Wiemy wszyscy jak wygląda przesunięcie. Każdy punkt definiujący naszą figurę przesuwamy o jakiś odcinek ( wektor ), który mówi o ile ten obiekt ma się nam przemieścić. Czyli po prostu do współrzędnych naszego obiektu dodajemy współrzędne wektora przesunięcia. Myślę, że jest to zupełnie oczywiste. Załóżmy, że nasz obiekt składa się z jednego punktu, o współrzędnych ( x, y ) i chcemy go przesunąć o wektor o współrzędnych ( dx, dy ). Matematycznie będzie to wyglądać następująco:



Równania w zasadzie bardzo proste i można by tutaj już skończyć nasze rozważania. No ale ja upierał się będę nadal przy macierzach. Dlaczego ? Mam nadzieję, że po przeczytaniu całego artykułu wszystko się wam wyjaśni. Zauważmy, że zarówno z pary współrzędnych punktu jak i wektora przesunięcia możemy sobie zrobić macierze. Więc niech:

    

Wtedy powyższe równania dwa przekształcają się w jedno równanie z udziałem macierzy:


lub inaczej i bardziej szczegółowo na to patrząc:


Mając funkcję, która dodaje nam macierze, możemy sobie więc przeprowadzić operację przesuwania. Ktoś może wzruszy ramionami i powie, że to nic niezwykłego bo w tej funkcji mnożącej macierze byłoby dokładnie dokładnie to samo co na początku naszych rozważań. Będzie miał po trochę racji, ale do czasu. No ale my nie przejmujmy się niedowiarkami, tylko brnijmy dalej.
  • Skalowanie
Następną operacją jaką będzie można wykonać będzie skalowanie punktów. Brzmi to trochę bez sensu, bo punkt jako taki nie ma wymiarów i nie można go traktować jako obiektu, który można zeskalować, ale nie to miałem na myśli. Skalowanie punktów polega na mnożeniu ich współrzędnych przez jakąś liczbę. Jeśli mamy więc model złożony z kilu punktów to pomnożenie współrzędnych punktów go tworzących spowoduje jego powiększenie ( jeśli współczynniki będzie większy niż 1 ) lub zmniejszenie jeśli współczynnik będzie mniejszy przy założeniu że obiekt ten leży w środku układu współrzędnych. Jeśli ktoś nie wierzy, to niech sprawdzi na zwykłej kartce papieru w kratkę. Warto zauważyć, że każdą współrzędną można mnożyć przez inną liczbę i osiągać w ten sposób różne ciekawe efekty. Równania dla skalowania można zapisać czysto matematycznie jako:



A równania macierzowe ? Zauważmy, że będziemy mnożyć teraz macierze, więc czy to będzie takie oczywiste ? Przypomnijmy sobie za pomocą poprzedniego tutorialu jak mnoży się macierze i poczyńmy tutaj pewne spostrzeżenia. Jak pamiętamy, aby pomnożyć macierze, jedna powinna mieć taką samą ilość kolumn w pierwszej z mnożonych macierzy jak i wierszy w drugiej. Jeśli byśmy zaczęli układać równania macierzowe dla naszych powyższych równań to zgodnie z powyższym założeniem naszych macierzy nie da się przez siebie pomnożyć, ponieważ obie mają po jednej kolumnie i po dwa wiersze. Aby było to możliwe koniecznym będzie uzupełnienie którejś z macierzy składowych o nowe elementy, jednak takie, które nie spowodują żadnych zmian w wyniku ! Zastanówmy się którą z macierzy będzie nam wygodniej i bez komplikacji zmienić. Gdybyśmy chcieli na przykład rozszerzyć macierz zawierającą współrzędne punktu. Pierwsze co się nasuwa to to, że musielibyśmy to zrobić dla wszystkich punktów naszej bryły, których może być całkiem sporo. Po drugie nie wiadomo czy nie trzeba by było zacząć przechowywać jakiś dodatkowych informacji dotyczących współrzędnych wierzchołków. Więc jakby nie patrzeć nie jest to zbyt korzystne. Zwróćmy więc uwagę na naszą macierz skalowania. Od razu narzuca się jedna, ważna myśl. Ta macierz będzie przecież tylko jedna ! Będziemy ją mogli zastosować do wszystkich wierzchołków na raz. Jest bardzo ważne dla nas spostrzeżenie i można by rzec, że nawet decydujące. Zajmiemy się więc uzupełnieniem tej macierzy, aby można ją było pomnożyć przez tę, zawierającą współrzędne punktów. I cóż więc należy zrobić, żeby móc skalować i jednocześnie zachować zasady mnożenia macierzy ? Całe szczęście już dawno ktoś pomyślał za nas i teraz my tylko możemy to wykorzystać. Macierz skalowania będzie wyglądać tak:


Jak ktoś nie wierzy, że takie rozszerzenie niczego nie zmieni w macierzy wynikowej dla punktu P1 niech sobie pomnoży ręcznie nasze macierze a sam się przekona. Mnożenie jest w zasadzie bardzo proste i można je wykonać na kartce z ołówkiem w ręce. Równania macierzowe będą wyglądać następująco:



  • Obracanie
Mieliśmy przesuwanie i skalowanie, czas więc na najbardziej efektowną operację, czyli obracanie. W czasach, kiedy nie było jeszcze D3D ani OpenGL a świat grafiki komputerowej kręcił się wokół trybu 13h i bezpośredniego dostępu do pamięci obrót figur w pełnym 3D był czymś, co wywoływało na widzach największe wrażenie. Dzisiaj jest to jedna z podstawowych operacji i nie sposób już sobie wyobrazić jakiegokolwiek przykładu, w którym coś by się nie obracało. Pamiętam do dziś optymalizację tablic sinusów i cosinusów, sprytne liczenie wartości kątów i tym podobne sztuczki w asemblerze, ech, gdzie te czasy... Ale powróćmy może do naszych rozważań. Na początek weźmy łatwiejsze obracanie, wokół środka układu współrzędnych. Ktoś oczywiście kiedyś za nas pomyślał i wymyślił takie oto równania na obrót i nowe współrzędne:


Jak widać nie jest to podobne ani do przesuwania ani do skalowania. Składników jest więcej niż poprzednio, ale paradoksalnie nam to tylko ułatwi sprawę ! Nie będziemy musieli już kombinować z naszą macierzą, nie będziemy musieli jej uzupełniać. Wystarczy odpowiednio zakombinować z ułożeniem czynników równań w macierzach i dostaniemy to co chcemy, czyli równanie macierzowe. Macierz obrotu będzie wyglądać tak:


Natomiast równania macierzowe dla obrotu wokół środka układu współrzędnych:




Ktoś niewierzący, że tak będzie znowu może sobie sprawdzić mnożąc macierze ręcznie i porównując wynik z równaniami, które podałem wcześniej. Okaże się, że znowu miałem rację. Wbrew pozorom okazało się, że równania najbardziej skomplikowane można było przerobić na równania macierzowe w najprostszy sposób.
  • Współrzędne jednorodne
Teraz należałoby omówić przekształcenia w przestrzeni 3D, ale zanim to nastąpi powinniśmy sobie powiedzieć o czymś takim jak układ współrzędnych jednorodnych. Cóż to jest takiego. Jeśli popatrzeć wyżej to da się zauważyć jedną, dosyć charakterystyczną rzecz. Otóż skalowanie i obracanie punktów polega na mnożeniu odpowiednich macierzy przez siebie, natomiast przesuwanie to dodawanie macierzy. Stwarza nam to trochę niewygodną sytuację w momencie kiedy przyjdzie nam ochota na przykład składać przekształcenia w celu przeprowadzenia skomplikowanej operacji. Na czym z kolei polega składanie przekształceń ? Otóż wyobraźmy sobie, że mamy na naszej scenie punkt, który najpierw chcemy sobie obrócić o jakiś kąt a potem przesunąć w jakiś punkt na ekranie. Macierzowe postacie naszych równań dają nam do ręki bardzo fajną rzecz, a mianowicie taką, że macierze kolejnych przekształceń można wymnożyć przez siebie i po zaaplikowaniu tak stworzonej nowej macierzy naszym danym zostaną one odpowiednio przekształcone. Wiemy, że mnożenie macierzy nie jest przemienne, czyli A*B to nie to samo co B*A , więc na pewno też obrót i przesunięcie to nie to samo co przesunięcie i obrót. Tu od razu widzimy jeszcze jedną, bardzo ważną cechę przekształceń - one też nie są przemienne ! Bardzo ważna jest kolejność ich przeprowadzania o czym nie raz będziemy mieli jeszcze okazję się przekonać. I wszystko byłoby pięknie, gdyby nie jeden, malutki szkopuł - dodawanie w przypadku macierzy przesunięcia. W takim przypadku nie da się oczywiście mnożyć macierzy przez siebie bo wyjdą nam bzdury. Trzeba więc zrobić coś, aby macierz przesunięcia można było mnożyć przez współrzędne punktów i żeby wychodziło wszystko w porządku. Ktoś pewnie pomyśli, że można było to zrobić już na początku, ale niech spróbuje pokombinować tak, żeby móc pomnożyć macierze w przypadku przesunięcia bez jakiejś skomplikowanej gimnastyki.
Aby móc traktować przesunięcie jako mnożenie macierzy, punkty powinny więc być przeniesione do układu współrzędnych jednorodnych. Układ taki charakteryzuje się tym, że do każdej współrzędnej punktu, bez względu czy leży on na płaszczyźnie czy w przestrzeni dodajemy jeszcze jedną, która umożliwi nam takie przekształcenie punktów, że wszystkie operacje macierzowe na nich będą mogły być traktowane jako mnożenia macierzy. Cechą charakterystyczną współrzędnych w układzie jednorodnym jest to, że różne zestawy wartości współrzędnych mogą reprezentować ten sam punkt. Aby to zrozumieć przyjrzyjmy się może punktom na płaszczyźnie 2D. Normalnie punkt taki ma współrzędne ( x, y ). Jeśli przeniesiemy go do układu współrzędnych jednorodnych dostaniemy trzy współrzędne ( x, y, w ). Układ jednorodny ma ograniczenie, polegające na tym, że współrzędna "w" nie może być równa 0. Jeśli przyjmiemy powyższe założenia to przy współrzędnej "w" różnej od zera możemy współrzędne naszego punktu podzielić przez jej wartość i otrzymamy ( x/w, y/w, 1). Wtedy też wartości x/w i y/w są nazywane współrzędnymi kartezjańskimi i to są te, które my dobrze znamy. Wspominałem kilka linii wyżej, że różne zestawy współrzędnych jednorodnych mogą reprezentować ten sam punkt we współrzędnych kartezjańskich, czy już widzicie dlaczego ? Weźmy sobie na przykład punkty ( 2, 3, 6 ) i ( 4, 6, 12 ). Jeśli podzielimy kolejne współrzędne przez współrzędną "w" to otrzymamy w obu przypadkach punkt ( 1/3, 1/2, 1 ). Zatem warunkiem tego, że dwa różne punkty w przestrzeni jednorodnej przedstawiają ten sam punkt na płaszczyźnie jest to, że jeden punkt musi być wielokrotnością drugiego ( mowa oczywiście o poszczególnych współrzędnych ). Warto też dodać, że większość dzisiejszych pakietów do tworzenia grafiki 3D używa właśnie układu współrzędnych jednorodnych a współrzędna "w" przyjmuje przeważnie wartość 1, co powoduje to, że współrzędne x i y praktycznie się nie zmieniają.
Wracając do naszego przesunięcia, dodawania i mnożenia macierzy. Ponieważ nasz punkt będzie miał teraz trzy współrzędne macierze poszczególnych przekształceń zmienią się w znaczący sposób, ale jednocześnie uzyskamy możliwość przeprowadzenia wszelkich operacji w ten sam sposób. Zacznijmy więc od przesunięcia. Nasze równanie macierzowe przyjmie postać:


Macierze skalowania i obrotu nie zmienią się tak znacznie jak przesunięcie, bo do nich tylko dodamy wiersze i kolumny, żeby zgadzał nam się warunek na mnożenie. Poszczególne będą wyglądać następująco:




  • Uwaga
Czasem, czytając różne podręczniki spotkacie się z odwrotnym mnożeniem macierzy, czyli współrzędne punktu będą zapisane jako wiersz a nie jako kolumna macierzy. Jak napisałem mnożenie macierzy nie jest przemienne ( za wyjątkiem mnożenia macierzy i odwrotnej do niej przez siebie ), więc aby wszystko nam grało w przypadku drugim konieczne będzie przetransponowanie wszystkich macierzy biorących udział w określonej operacji. A co to transponowanie mam nadzieję, że już wiecie.

  • Składanie przekształceń
Przy omawianiu układu jednorodnego wspomniałem o czymś takim jak składanie przekształceń. Podałem przykład obracania i przesuwania dokonywanych po sobie. Reprezentacja macierzowa naszych działań umożliwia nam zrobienie pewnej fajnej rzeczy z naszymi przekształceniami. Otóż, jeśli zapragniemy sobie zrobić to nasze przykładowe przekształcenie ( obrót i przesunięcie ) to możemy stworzyć sobie macierz, której pomnożenie przez macierz naszych współrzędnych spowoduje to, że te dwie operacje wykonane zostaną od razu. Cel tego jest oczywisty - zamiast robić poszczególne przekształcenia po kolei my stworzymy sobie jedną macierz, która będzie robić to, co nam potrzeba a program na pewno zyska na efektywności.
Aby dobrze pokazać składanie przekształceń weźmy sobie problem następujący. Wiemy już jak obracać punkty wokół środka układu współrzędnych. A teraz chcielibyśmy obrócić nasz punkt wokół dowolnego innego punktu leżącego na płaszczyźnie. Co w takim wypadku ? Ano pomoże nam w tym właśnie złożenie przekształceń. Rozbijmy sobie nasz problem niewątpliwie trudny na trzy mniejsze problemy:

  • Ponieważ potrafimy sobie obracać punkt wokół środka układu współrzędnych więc pierwszą rzeczą będzie takie przesunięcie wszystkich punktów naszej bryły i środka obrotu, żeby ten ostatni znalazł się w środku układu współrzędnych.
  • Mając środek obrotu w środku układu współrzędnych bez problemu obrócimy sobie nasz obiekt.
  • Przesunięcia z powrotem wszystkich punktów w to samo miejsce, gdzie były przed wykonaniem obrotu.
Jak łatwo sobie wyobrazić po tych kilku operacjach nasz obiekt obróci się wokół punktu, który my obraliśmy sobie za środek obrotu. Całe to nasze przekształcenie w zapisie macierzowym wyglądać więc będzie następująco:


Zwróćmy uwagę na macierze przesunięcia i na współczynniki przesunięcia. U nas są to po proste współrzędne punktów a dlaczego powinno być wiadomo od razu po uważnej lekturze lekcji poświęconej wektorom. Wspominałem tam o wektorach, które określają położenie punktów w przestrzeni. Po prostu wektor łączący środek układu i punkt w przestrzeni lub na płaszczyźnie będzie miał takie same współrzędne jak punkt, który jest jego końcem. Dlatego właśnie jako wektor przesunięcia podajemy współrzędne naszego punktu, raz w jedną stronę raz w drugą.
Tę technikę będziemy mogli stosować wszędzie tam, gdzie trzeba będzie wykonać jakieś bardziej złożone operacje typu obrót czy skalowanie na obiektach nie leżących w środku układu współrzędnych. Jest ona w sumie bardzo prosta i sprowadza się do podstawowej sekwencji operacji - przesunięcia obiektu, do środka układu współrzędnych, dokonania operacji i przesunięcia go z powrotem na właściwe miejsce.

  • Macierz ortogonalna
Wróćmy na chwilę teraz do naszej macierzy obrotów i przyjrzyjmy się jej bliżej:


W górnej lewej podmacierzy 2 x 2 potraktujmy każdy z dwóch wierszy jako wektor i obliczmy ich długości:


Dla obydwu wierszy jak łatwo zauważyć oczywiście będzie to samo. Z tożsamości geometrycznej znanej ze szkoły nie wiem czy nie podstawowej wynika, że długość ta wynosi 1. Wektory te więc są jednostkowe. Policzmy też gdzieś na boku ich iloczyn skalarny, który wyjdzie nam 0. To zaś sugeruje nam prostopadłość obu wektorów ( kąt 90 stopni pomiędzy nimi ), jeśli ktoś nie wierzy niech natychmiast udaje się do lekcji o wektorach. Macierz, której poszczególne wiersze są jednostkowe i prostopadłe do siebie ( jako wektory ) będziemy nazywać macierzą ortogonalną. Po cóż nam takie cudo będzie potrzebne ? Jeśli teraz pomnożymy naszą macierz obrotu przez wektory jednostkowe osi X i Y to otrzymamy te wektory jednostkowe obrócone o dany kąt. Wektory te oczywiście nadal będą nadal prostopadłe do siebie ( inaczej mówiąc ortogonalne ). I teraz będziemy mogli zastosować pewną sztuczkę. Jeśli będziemy znali na przykład nasze obrócone wektory jednostkowe a nie będziemy znali kąta to będziemy mogli nadal stworzyć naszą macierz obrotu ! Tylko, że zamiast sinusów i cosinusów w naszej macierzy wstawimy sobie teraz poszczególne współrzędne naszych wektorów jednostkowych. A dlaczego ? Ano pomnóżmy naszą macierz obrotu przez wektory jednostkowe i co otrzymamy ? Jeśli dokładnie policzyliście to składowe obróconych wektorów jednostkowych przyjmą dokładnie takie same wartości jak poszczególne kolumny macierzy obrotu, kolejno dla osi x i y, prawda ? Więc jeśli mieliśmy gdzieś obrócone wektory jednostkowe, prostopadłe do siebie a nie znaliśmy macierzy obrotu to teraz już będziemy potrafili ją zawsze wyznaczyć ! Jakie to będzie miało zastosowanie dobitnie przekonamy się przy wyznaczaniu macierzy widoku w którejś z kolejnych lekcji. Ale zapamiętajcie to, bo to bardzo ważne.

Wiemy już dużo o przekształceniach na płaszczyźnie 2D czas więc przenieść się w trzeci wymiar i przekonać się jak będzie się miała sytuacja w takim przypadku. Powiedzieliśmy sobie o układzie jednorodnym i nadal będziemy się go tutaj trzymać. Przy operacjach 2D, w układzie tym przekształcenia reprezentowaliśmy jako macierze 3 x 3 ( aby można było traktować przesunięcie jako mnożenie ). Analogicznie w przestrzeni 3D dodamy do naszych współrzędnych czwartą składową "w". Nie traktujmy tego jak czegoś namacalnego, bo i tak nie damy rady - na razie nie potrafimy sobie wyobrazić geometrycznej, czwartej składowej obiektu, jej będziemy tylko używać do umożliwienia jednorodności naszego układu współrzędnych. Tak samo jak na płaszczyźnie dwie czwórki współrzędnych reprezentują ten sam punkt jeśli jeden jest niezerową wielokrotnością drugiego, więc wartość w = 0 jest absolutnie niedopuszczalna. Ale wracając do naszych prostych przekształceń. Większość będzie stanowiła niemal dokładnie odwzorowanie tych, znanych nam z układu 2D. Tak więc przesunięcie będzie tylko uzupełnione o jedną składową "z" i raczej nic wielkiego w naszym równaniu się nie stanie. Macierz naszego przekształcenia będzie wyglądała następująco:


Skalowanie będzie wyglądało tak:


Z obrotami będzie ciekawiej. Wszyscy chyba potrafimy sobie wyobrazić jak wygląda układ współrzędnych w przestrzeni 3D. Obrotów będziemy tutaj w przeciwieństwie do 2D dokonywać nie wokół punktów ale wokół osi, które będą się znajdować w przestrzeni. I tak idąc po kolei najpierw zaczniemy od tego, który może nam się już zacząć nawet kojarzyć. Najczęściej zdarza się tak, że patrzymy na ekran wzdłuż osi z naszego układu współrzędnych. W 2D obrotu dokonywaliśmy wokół punktu. Jeśli teraz wyobrazimy sobie taki obrót na ekranie to przy odrobinie wysiłku umysłowego jasne stanie się to, że obrót ten w przestrzeni 3D dokonywany jest de facto wokół osi z. Macierz przekształcenia, którą trzeba będzie zaaplikować naszym wierzchołkom wyglądać będzie tak:


Analogicznie postępując i posługując się naszą wyobraźnią dojdziemy do pozostałych macierzy przekształceń, czyli dla osi x:


oraz y:


Ze składaniem przekształceń będzie dokładnie tak samo, jak w przestrzeni 2D. Potrzebna będzie może tylko odrobinkę większa wyobraźnia, tym razem przestrzenna, żeby się nie pogubić w gąszczu wszystkich potrzebnych operacji, bo tych będzie przybywać w zastraszającym tempie w zależności od rosnącej złożoności. Tak naprawdę istota samych przekształceń jest bardzo prosta i chyba powinniście wszystko tutaj zrozumieć. Jeśli komuś się nudzi to może sobie w ramach rozrywki albo praktyki powyprowadzać ze wzorów macierzowych oryginalne wzory na przykład na obroty w przestrzeni 3D. W pakietach graficznych będziemy się posługiwali gotowymi funkcjami do tworzenia podobnych macierzy, także do ich mnożenia i dokonywania składania przekształceń. Zresztą na pewno pisząc już w 3D robiliście to bardzo wiele razy. Nam zaś pozostanie teraz omówienie kilku ważnych przekształceń przy inicjalizacji świata 3D i powrócimy wkrótce do świata Direct3D i zajmiemy się bardziej skomplikowanymi technikami. No to do zobaczenia w przyszłym tutorialku...

Wersja do druku (pdf)

©Copyright by Robal   



Tutoriale - Matematyka
Nasze newsy s� w RSS: backend.php
PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Tworzenie strony: 0.05 sekund

:: Layout strony został stworzony przez www.nukemods.com w oparciu o styl phpbb2 Helius, którego autorem jest Cyberalien ::