Jak radzić sobie z różnicami między współrzędnymi ekranu 2D a współrzędnymi kartezjańskimi

23
  • Większość układów współrzędnych ekranu / mapy bitowej 2D ma dodatnią oś Y skierowaną w dół (z punktem początkowym w lewym górnym rogu).
  • Jest to sprzeczne z tym, jak większość ludzi myśli geometrycznie z dodatnią osią Y skierowaną w górę (z punktem środkowym).

Jak większość gier zarządza dwoma różnymi układami współrzędnych 2D? Istnieją dwa główne typy współrzędnych (ekran vs. kartezjański), ale może istnieć wiele różnych przestrzeni współrzędnych: przestrzeń duszka, przestrzeń świata, przestrzeń widoku, przestrzeń ekranu itp.

Tło:

Pierwotnie dopasowałem współrzędne świata w mojej grze do konwencji współrzędnych ekranu 2D. Dzięki temu korzystanie z procedur rysowania grafiki było bardzo naturalne, ale podczas korzystania z funkcji trygonometrycznych, takich jak atan2 (), pojawiły się subtelne problemy. Wyniki podawania współrzędnych ekranu atan2 () 2D są bardzo mylące, ponieważ atan2 () zakłada dodatnie punkty osi y w górę.

Zmieniłem więc swoje współrzędne świata, aby podążać za klasycznym kartezjańskim układem współrzędnych (z początkiem w lewym dolnym rogu ekranu). Rozumowanie za pomocą atan2 () jest znacznie prostsze, ale teraz trudniej jest robić inne rodzaje rozumowania:

  • Jeśli kliknę tutaj ekran, jaki duszek znajduje się pod nim?
  • Gdzie kliknąłem tego duszka?
  • Jeśli duszek zostanie narysowany w złym miejscu, co zostało niepoprawnie obliczone? Współrzędne ekranu czy współrzędne świata?

Zdaję sobie sprawę, że konwersja z ekranu na współrzędne kartezjańskie polega po prostu na skalowaniu wartości y o -1 z opcjonalnym tłumaczeniem obu wartości (x, y). Bardziej interesują mnie sprawdzone metody projektowania gier:

  • Czy większość gier po prostu przestrzega konwencji współrzędnych ekranu i zmienia sposób myślenia o tym, jak powinny działać atan2 ()?
  • Kiedy / jak przeprowadzane są konwersje układu współrzędnych? (Korzystanie z macierzy, abstrakcji OOP itp.)
  • Czy lokalizacje duszka są przechowywane jako środek duszka lub jeden z rogów? Wysokość / szerokość duszka idąca w „złym” kierunku wydaje się być częstym problemem, gdy je narysuję.

Chociaż moje pytanie dotyczy głównie gier 2D, wydaje się, że OpenGL używa układu współrzędnych, w którym oś Y skierowana jest w górę. OpenGL musi ostatecznie rzutować te współrzędne 3D na układ współrzędnych ekranu 2D. Być może pewne wskazówki można znaleźć w metodzie OpenGL ...

Leftium
źródło

Odpowiedzi:

8

Po wypróbowaniu wszystkich możliwych sposobów zrobienia tego, przekonałem się, że jeśli jest to wyłącznie gra 2D, po prostu użyj systemu rysowania ekranu, to znacznie ułatwi Ci życie. Sin, Cos i atan2 muszą być używane nieco inaczej, ale tę niedogodność łatwo zrekompensować prostotą zrozumienia, w którą stronę w górę, w dół, w prawo i w lewo. Polecam również pracę w pikselach zamiast w metrach w grach 2D - o wiele łatwiej jest myśleć o odległościach na ekranie, a szanse na zmianę całej skali gry są bliskie zeru.

„Jak większość gier zarządza dwoma różnymi układami współrzędnych 2D?”

  • większość gier 2D widziałem źródło do korzystania z systemu ekranu, ale każda istota powinna znać swoją przestrzeń świata, pozwól swojemu menedżerowi rysunków przekonwertować to na pozycję ekranu. W tym momencie wykonasz dowolną transformację macierzy, jakiej potrzebujesz.

„Czy lokalizacje duszka są przechowywane jako środek duszka lub jeden z rogów?”

  • Jeśli pracujesz od środka, rotacja jest prostsza, chociaż będziesz chciał poznać również narożniki.

„Być może jakieś wskazówki można znaleźć w metodzie OpenGL ...”

  • Silniki 3D to zupełnie inna sprawa. Ponieważ mają prawdziwe kamery, pozycja ekranu może się znacznie różnić od pozycji na świecie. W przypadku gry odgórnej pracowałbyś w osiach X i Z, a nie w X i Y z jednej strony.
Iain
źródło
1

Być może upraszczam tutaj rzeczy, ale chciałbym, aby jakikolwiek podsystem 2D / UI zajmował się ściśle współrzędnymi „ekranowymi”. Będziesz miał dwie macierze: ScreenToCartesianTransform i CartesianToScreenTransform. Po odebraniu zdarzeń wejściowych myszy współrzędne myszy zostaną przekształcone za pomocą CartesianToScreenTransform, zanim zostaną przekazane do menedżera wprowadzania danych w systemie 2D / UI. Stamtąd system interfejsu użytkownika przeprowadzałby test trafień za pomocą układu współrzędnych ekranu i odpowiednio obsługiwał (lub nie obsługiwał) zdarzenie. Jeśli zdarzenie wprowadzania myszy nie jest obsługiwane przez interfejs 2D / UI, może zostać przekazane do układu 3D (jeśli taki istnieje) przy użyciu oryginalnych, nietransformowanych współrzędnych.

Ponieważ system 2D / UI zajmowałby się tylko współrzędnymi „ekranowymi”, jego geometria musiałaby zostać przekształcona za pomocą ScreenToCartesianTransform przed przetworzeniem przez silnik renderujący.

Mike Strobel
źródło
W rzeczywistości, w zależności od używanego zestawu narzędzi, zdarzenia wprowadzania myszy mogą być już we współrzędnych ekranowych. W takim przypadku nie przekształciłbyś ich dla systemu 2D / UI, ale zrobiłbyś to dla systemu 3D (jeśli taki istnieje).
Mike Strobel,
0

Wolę używać drzewa wyświetlania jak we Flashu. Będę miał węzeł główny (widok gry), który zawiera dziecko dla świata (węzeł świata) i jedno na górze dla interfejsu. Wewnątrz węzła świata będą węzły dla obiektów w świecie gry.

Następnie po prostu przekształcam węzeł świata. Wraz z tłumaczeniem (panoramowanie z kamery) i skalowaniem proporcjonalnym (zoom z kamery) stosuję również dwie inne transformacje:

  • Skala -1 y do odwrócenia układu współrzędnych.
  • Skalowanie do konwersji jednostek świata (metry) na jednostki ekranu (piksele)

Następnie używam współrzędnych y-up / world w kodzie rysowania obiektów gry i współrzędnych y-down / screen w kodzie rysunku HUD, które są bardzo naturalne.

Aby odpowiedzieć na pytania typu „jaki obiekt klikam”, używam metod węzła wyświetlania do konwersji współrzędnych między układami współrzędnych (takich jak globalToLocali odwrotnie we Flashu).

Nawiasem mówiąc, atantak naprawdę nie działa inaczej, gdy y jest w dół, wystarczy pomyśleć o wszystkich kątach jako zgodnych z ruchem wskazówek zegara, a nie przeciwnie do ruchu wskazówek zegara.

Bart van Heukelom
źródło
0

OpenGL, podobnie jak DirectX, ma osie X i Z wzdłuż płaszczyzny poziomej i Y skierowane do góry.
Nigdy nie miałem żadnych problemów ze współrzędnymi ekranu i myślę, że najłatwiejszym sposobem byłoby po prostu potraktowanie tego, jak to jest: jeśli coś, na przykład atan2, nie lubi, to zmieniają podawane parametry.

Jeśli używasz współrzędnych względnych lub lokalnych, takich jak wykres sceny, dobra jest prosta funkcja, taka jak ToGlobalCoords (). W rzeczywistości, jeśli chcesz dowiedzieć się więcej na temat pozycjonowania przestrzennego, wykresów scen i localToGlobal, to darmowy fragment z Game Engine Architecture.

Duszki są rysowane od lewego górnego rogu lub (0,0) źródła. Powody, dla których są spowodowane lewym górnym źródłem okna.

Trochę głupio wydaje się zmiana układu współrzędnych okna, co znacznie utrudniłoby wprowadzanie danych, które odgrywają większą rolę w większości gier niż trygon. To także oddziela cię od normy i użytkowników Twojego kodu.

Kaczka komunistyczna
źródło