Posts tagged ‘vectors’

Kwantowanie kierunku

2009-03-13 17:20

Wszyscy wiedzą jak, mając dane dwa punkty, wyznaczyć wektor kierunkowy od pierwszego punktu do drugiego. Niekiedy jednak nie chcemy, aby możliwe było uzyskanie dowolnego kierunku. Może tak być np. przy poruszaniu jednostkami na mapie, gdy z jakiegoś powodu chcemy dopuścić, powiedzmy, tylko 8 czy 16 podstawowych kierunków. W jaki sposób należy wtedy “zaokrąglić” nasz dowolny wektor, uzyskany jako różnica aktualnej pozycji jednostki i np. miejsca kliknięcia myszką przez gracza?

Pierwszym możliwym sposobem jest zamiana jego reprezentacji ze współrzędnych prostokątnych (x, y) na biegunowe (r – długość, theta – kąt między dodatnią półosią X a wektorem). Jest to możliwe przy pomocy obecnej w wielu językach funkcji atan2(y, x). Wystarczy potem sprawdzić, któremu wzorcowemu wektorowi jest najbliższy otrzymany kąt.

Swego czasu znalazłem jednak nieco inny sposób, który daje się zastosować bez zmiany reprezentacji wektora. Oryginalnie służył on do wyboru jednego z ośmiu podstawowych kierunków, ale nietrudno było zauważyć, że da się go trochę uogólnić:

  1. VEC2 Quantize(const VEC2 v, int k)
  2. {
  3.     v.Normalize();
  4.     v *= k;
  5.     return VEC2((int)Round(v.x), (int)Round(v.y));
  6. }

Użyta tutaj funkcja Round(t) oznacza zaokrąglenie w stronę najbliższej liczby całkowitej, czyli floor(t + 0.5). Współczynnik k kontroluje natomiast, ile wektorów wzorcowych znajduje się w naszej “róży wiatrów”. Powyższa funkcja dzieli bowiem kąt pełny na dokładnie 2k+2 wycinków, dając tyle też możliwych wektorów wynikowych. Osiem kierunków otrzymamy więc dla k = 1, szesnaście dla k = 2, itd. Teoretycznie możliwe są też ułamkowe wartości współczynnika, co najprawdopodobniej pozwałoby kontrolować “czułość dopasowania” wektora do wzorca. Nie podjąłem się jednak opracowania jakiejś ścisłej zależności :) Jedyne co udało mi się zaobserwować to to, że dla k = 2/3 otrzymujemy dopasowanie do czterech podstawowych kierunków (N, S, W, E).
Ogólnie więc nie jest to może epokowe odkrycie w dziedzinie wektorologii stosowanej, ale istnieje szansa, że komuś do czegoś się przyda ;]

Tags: , ,
Author: Xion, posted under Programming » Comments Off on Kwantowanie kierunku

Wektory w różnych przestrzeniach

2008-07-28 17:26

Kiedy zaczynamy uczyć się programowania, dowiadujemy się, że zmiennym przypisane są zawsze konkretne typy, których należy się trzymać. Trochę później, gdy zajmujemy się już shaderami i programowalnym potokiem graficznym, okazuje się, że większość wartości jest tam tego samego typu (wektor trzech lub czterech floatów). Różnią się one jednak przypisaną im semantyką, czyli znaczeniem w opisie wierzchołka lub piksela (POSITION, NORMAL, COLOR, i tak dalej).
Jednak sama semantyka nie jest jedyną cechą charakterystyczną danego wektora. Nawet mając do czynienia z dwoma wektorami “geometrycznymi” (czyli opisującymi pozycję lub normalną, a nie np. kolor), nie zawsze możemy wykonywać na nich łączne operacje. Należy bowiem zadbać o to, by wektory te znajdowały się w tej samej przestrzeni. W przeciwnym razie konieczne jest odpowiednie przekształcenie, co sprowadza się do pomnożenia przez jakąś macierz.

Aby łatwiej zorientować się, z którą przestrzenią mamy do czynienia, można stosować odpowiednie nazewnictwo, na przykład w postaci sufiksów. Przyrostki te mogą być przyporządkowane choćby następująco:

  • _o (np. vPos_o) niech odpowiada przestrzeni obiektu (object space), związanej z układem lokalnym konkretnej instancji modelu
  • _w (np. vPos_w) może oznaczać globalną przestrzeń świata (world space)
  • _v to z kolei przestrzeń widoku (view space), związana z pozycją obserwatora
  • _t możemy przyporządkować do tangent space przy obliczeniach związanych z oświetleniem
  • _l może w końcu być przyrostkiem wektorów w przestrzeni związanej z pozycją konkretnego światła

Oczywiście cały ten pomysł na kilometr śmierdzi sławetną notacją węgierską, jednak w tym przypadku “dekorowanie” nazw zmiennych ma znacznie głębszy sens. Błędów spowodowanych operacjami na wektorach z różnych przestrzeni nie wykryje nam bowiem żaden kompilator, a ich samodzielne wyśledzenie bywa bardzo trudne (podobnie jak większości innych błędów matematycznych). Dlatego należy zawsze zwracać baczną uwagę na to, z jaką przestrzenią aktualnie pracujemy, i stosować jeśli nie specjalne nazewnictwo, to chociaż szczegółowe i jednoznaczne komentarze.

Tags: ,
Author: Xion, posted under Programming » 4 comments

Układy odniesienia

2007-10-02 19:06

Programując grafikę czy choćby cokolwiek, co ma się ostatecznie pokazać na ekranie, cały czas operuje się współrzędnymi w przestrzeni. Wówczas trzeba zawsze pamiętać, że ten zestaw liczb – zwykle X, Y i ewentualnie Z – nie istnieje sam dla siebie i zawsze jest podawany względem czegoś. Tak więc wszystkie współrzędne są względne, bo nawet nazywane “bezwzględnymi” różnią się tylko tym, że ich punkt odniesienia jest wyjątkowo dobrze zdefiniowany – na przykład jako lewy górny róg ekranu lub punkt (0,0,0) nieprzetransformowanego układu sceny 3D.

Kłopoty zaczynają się wtedy, gdy zaczynamy nieświadomie mieszać koordynaty korzystające z innych układów odniesienia. Nadal czasami mi się to zdarza w kodzie systemu GUI, mimo że starałem się bardzo dokładnie określić względem czego jest określona np. pozycja danej kontrolki i jakie przekształcenia (głównie odpowiednia translacja) są wykorzystywane przy rysowaniu każdego elementu.
To wszystko jest oczywiście w dwóch wymiarach. W 3D potencjalnych punktów odniesienia jest nawet więcej; wśród nich mamy chociażby ten związany z kamerą, z modelem, ze światłem, i tak dalej. A co gorsza, ocena czy taki lub inny błąd wynika właśnie z pomylenia różnych układów współrzędnych jest trudniejsza właśnie ze względu na obecność tego trzeciego wymiaru.

Wniosek stąd taki, że należy pamiętać o używanym aktualnie układzie odniesienia. Łatwo bowiem napisać:

  1. void Foo(float x, float y, float z);

i za jakiś (niedługi) czas zastanawiać się, względem czego te x, y czy z powinno tak naprawdę być liczone. A podejrzewam, że u większości programistów umiejętność rozwiązywania tego typu łamigłówek jest dość… względna :)

Tags:
Author: Xion, posted under Programming » 1 comment
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.