2D 화면 좌표와 직교 좌표의 차이점을 다루는 방법


23
  • 대부분의 2D 화면 / 비트 맵 좌표 시스템은 양의 Y 축이 아래쪽을 향하도록합니다 (왼쪽 위 모서리에 원점이 있음).
  • 이것은 대부분의 사람들이 긍정적 인 Y가 가리키는 축과 기하학적으로 생각하는 방법을 카운터 까지 (중앙에 원점).

대부분의 게임은 서로 다른 2D 좌표계를 어떻게 관리합니까? 좌표에는 두 가지 주요 유형 (화면 대 데카르트)이 있지만 스프라이트 공간, 월드 공간,보기 공간, 화면 공간 등 여러 가지 좌표 공간이있을 수 있습니다.

배경:

원래 게임에서 월드 좌표를 2D 화면 좌표 규칙과 일치 시켰습니다. 이것은 그래픽 드로잉 루틴을 사용하는 것이 매우 자연 스럽지만 atan2 ()와 같은 삼각 함수를 사용할 때 미묘한 문제가 발생했습니다. atan2 ()가 양의 y 축을 가리킨다 고 가정하기 때문에 atan2 () 2D 화면 좌표를 공급 한 결과는 매우 혼란스러워합니다.

그래서 나는 세계 좌표를 고전적인 직교 좌표계 (화면의 왼쪽 아래에있는 원점)를 따르도록 변경했습니다. atan2 ()를 사용한 추론은 훨씬 간단하지만 이제는 다른 유형의 추론을하기가 더 어렵습니다.

  • 여기 화면을 클릭하면 어떤 스프라이트가 있습니까?
  • 그 스프라이트를 어디에서 클릭 했습니까?
  • 스프라이트가 잘못된 위치에 그려지면 무엇이 잘못 계산 되었습니까? 화면 좌표 또는 세계 좌표?

화면에서 데카르트 좌표로의 변환에는 (x, y) 값의 선택적 변환으로 단순히 y 값을 -1로 스케일링하는 것이 포함됩니다. 게임 디자인 모범 사례에 더 관심이 있습니다.

  • 대부분의 게임은 화면 좌표 규칙을 고수하고 atan2 ()와 같은 것들이 어떻게 작동해야하는지에 대한 생각을 바꾸나요?
  • 좌표계 변환은 언제 / 어떻게 수행됩니까? (매트릭스, OOP 추상화 등 사용)
  • 스프라이트 위치는 스프라이트의 중심 또는 모서리 중 하나로 저장됩니까? "잘못된"방향으로가는 스프라이트의 높이 / 너비는 내가 그릴 때 일반적인 문제인 것 같습니다.

내 질문은 주로 2D 게임에 관한 것이지만 OpenGL은 Y 축이 가리키는 좌표 시스템을 사용하는 것 같습니다. OpenGL은 결국 이러한 3D 좌표를 2D 화면 좌표 시스템에 투영해야합니다. 아마도 OpenGL의 방법에서 몇 가지 지침을 찾을 수 있습니다 ...

답변:


8

생각할 수있는 모든 방법을 시도해 보았을 때 순전히 2D 게임이라면 화면 그리기 시스템을 사용하면 인생을 훨씬 쉽게 만들 수 있습니다. Sin, Cos 및 atan2는 약간 다르게 사용해야하지만 이러한 불편 함은 위, 아래, 시계 방향 및 시계 반대 방향이 어떤 것인지 알기 쉬워 쉽게 해결할 수 있습니다. 또한 2D 게임의 경우 미터가 아닌 픽셀 단위로 작업하는 것이 좋습니다. 화면상의 거리를 생각하는 것이 훨씬 쉽고 게임의 전체 규모를 변경하려는 기회는 거의 없습니다.

"대부분의 게임은 서로 다른 2D 좌표계를 어떻게 관리합니까?"

  • 스크린 시스템을 사용하는 소스를 본 대부분의 2D 게임이지만 각 엔티티는 월드 공간을 알고 있어야하며 드로잉 관리자가이를 스크린 위치로 변환하도록합니다. 이 시점에서 필요한 행렬 변환을 수행 할 수 있습니다.

"스프라이트 위치는 스프라이트의 중심 또는 모서리 중 하나로 저장되어 있습니까?"

  • 가운데에서 작업하면 모서리를 알고 싶더라도 회전이 더 직선으로 이루어집니다.

"아마도 일부 지침은 OpenGL의 방법에서 찾을 수 있습니다 ..."

  • 3D 엔진은 완전히 다른 경우입니다. 실제 카메라가 있기 때문에 화면 위치가 세계 위치와 크게 다를 수 있습니다. 하향식 게임의 경우 X 및 Y가 아닌 X 및 Z 축에서 작업합니다.

1

여기서는 지나치게 단순화하고 있을지도 모르지만, 2D / UI 하위 시스템이 "스크린"좌표라는 것을 엄격하게 다루는 경향이 있습니다. ScreenToCartesianTransform과 CartesianToScreenTransform의 두 가지 행렬이 있습니다. 마우스 입력 이벤트가 수신되면 2D / UI 시스템의 입력 관리자로 전달되기 전에 CartesianToScreenTransform을 사용하여 마우스 좌표가 변환됩니다. 거기에서 UI 시스템은 화면 좌표 시스템을 사용하여 적중 테스트를 수행하고 그에 따라 이벤트를 처리 (또는 처리하지 않음)합니다. 마우스 입력 이벤트가 2D / UI에 의해 처리되지 않으면 변환되지 않은 원래 좌표를 사용하여 3D 시스템 (있는 경우)으로 전달 될 수 있습니다.

2D / UI 시스템은 "스크린"좌표 만 처리하므로 렌더링 엔진에서 처리하기 전에 ScreenToCartesianTransform을 통해 지오메트리를 변환해야합니다.


실제로, 사용중인 툴킷에 따라 마우스 입력 이벤트가 이미 화면 좌표에있을 수 있습니다. 이 경우 2D / UI 시스템에서는 변환하지 않지만 3D 시스템 (있는 경우)에서는 변환하지 않습니다.
Mike Strobel

0

플래시와 같은 디스플레이 트리를 선호합니다. 월드의 자식 (world node)과 HUD의 자식을 포함하는 루트 노드 (game view)를 갖게됩니다. 월드 노드 안에는 게임 월드의 오브젝트에 대한 노드가 있습니다.

그런 다음 간단히 월드 노드를 변환합니다. 변환 (카메라 패닝) 및 비례 스케일링 (카메라 줌)과 함께 두 가지 다른 변형도 적용합니다.

  • 좌표계를 뒤집기위한 -1 y 스케일입니다.
  • 월드 단위 (미터)를 화면 단위 (픽셀)로 변환하는 배율

그런 다음 게임 오브젝트 드로잉 코드에서 y-up / world 좌표를 사용하고 HUD 드로잉 코드에서 y-down / screen 좌표를 사용합니다.

"어떤 객체를 클릭하고 있는지"와 같은 질문에 답하기 위해 디스플레이 노드 방법을 사용하여 좌표계간에 좌표를 변환합니다 (예 : globalToLocalFlash의 역수)

그건 그렇고, atany가 내려 갔을 때 실제로 다르게 작동하지 않으므로 모든 각도를 시계 반대 방향이 아닌 시계 방향으로 생각하면됩니다.


0

DirectX와 마찬가지로 OpenGL은 수평 평면을 따라 X 및 Z 축을 가지며 Y는 위쪽을 향합니다.
나는 화면 좌표에 아무런 문제가 없었으며, 가장 쉬운 방법은 단순히 그것을 어떻게 처리하는 것이라고 생각합니다. atan2와 같은 것이 마음에 들지 않으면 공급되는 매개 변수를 변경하십시오.

장면 그래프와 같은 상대 또는 로컬 좌표를 사용하는 경우 ToGlobalCoords ()와 같은 간단한 함수가 좋습니다. 실제로 공간 위치, 장면 그래프 및 localToGlobal에 대해 더 배우고 싶다면 Game Engine Architecture에서 무료로 추출하십시오.

스프라이트는 왼쪽 상단 모서리 또는 (0,0) 원점에서 그려집니다. 이유는 창의 왼쪽 상단 원점 때문입니다.

창 좌표계를 변경하는 것은 약간 어리석은 것처럼 보이고 입력과 같은 것들을 trig보다 대부분의 게임에서 더 큰 역할을하므로 훨씬 더 어려워집니다. 또한 규범과 코드 사용자로부터 멀어지게합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.