육각 격자 저장


10

Unity3D를위한 작은 16 진 격자 프레임 워크를 만들고 있으며 다음과 같은 딜레마에 빠졌습니다. 이것은 내 좌표계입니다 ( here ).

여기에 이미지 설명을 입력하십시오

그것을 저장하는 방법을 모른다는 사실을 제외하고는 모두 잘 작동합니다. 원래는 이것을 2D 배열에 저장하고 이미지를 사용하여지도를 생성하려고했습니다.

한 가지 문제는 음수 값을 가졌다는 것입니다 (좌표를 약간 오프셋하여 쉽게 수정했습니다).

그러나이 좌표계로 인해 이러한 이미지 또는 비트 맵은 다이아몬드 모양이어야합니다.이 구조는 사각형 모양이므로 무언가를 해킹하더라도 많은 두통을 유발할 수 있습니다. 이 문제를 해결할 수있는 누락 된 것이 있습니까? 나는 단일 포럼에서 이것에 관한 포럼 게시물을 본 것을 기억하지만 더 이상 링크를 찾을 수 없습니다.

여기서 좌표 변환기 세트를 작성하는 것이 가장 좋은 솔루션입니까?

도움이 될 것이라고 생각되면 문제의 코드와 이미지를 게시 할 수 있습니다.


1
육각형 주위에 투명한 PNG 이미지 만 저장할 수 없습니까?
Markus von Broady

pngs와 arrays를 저장할 때의 주요 문제는이 좌표계를 그대로 유지하기 위해 포함해야 할 "공백"의 양입니다.
PeeC

1
"공백"이 투명 픽셀을 의미하는 경우 왜 그 수가 문제입니까?
Markus von Broady

아주 좋은 지적입니다. 대부분의 이미지 형식은 반복되는 패턴을 저장하는 많은 메모리를 낭비하지 않습니다. 그러나 여전히이 을 저장하려면 메모리를 많이 사용 하고 있습니다 (회색 픽셀은 빈 공간이며 다른 색상은 유효한 16 진수 좌표입니다).
PeeC

1
아, 타일 이미지가 아닌 그리드 데이터를 저장하고 있습니다! 왜 데이터 구조 (그리드)를 이진 파일로 저장하거나 JSON을 사용하여 인코딩하고 텍스트 파일로 저장하지 않겠습니까? 그래도 Unity의 기능을 모르겠습니다. 또한이를 확인하고 싶을 수도 있지만 동일한 색상의 영역이 PNG 형식으로 최적화 (느슨하게 압축)되어 있다고 생각합니다.
Markus von Broady

답변:


9

사용중인 평행 사변형 좌표는 작업하기가 더 쉽지만 직사각형 맵에서는 이상하다는 단점이 있습니다. 한 가지 방법은 오프셋 좌표와 함께 저장하지만 실제로 게임 로직에서 평행 사변형 좌표를 사용하는 것입니다.

관찰 : 맵의 각 행에서 그리드 데이터는 연속적입니다. 낭비되는 공간은 모두 왼쪽과 오른쪽에 있습니다.

솔루션 : 해당 행 내에서 0으로 표시된 열 대신 가장 왼쪽 열에서 시작하는 데이터를 저장 하십시오. 좌표계 에서 직사각형 맵의 첫 번째 열을 계산 한 다음 열 좌표에서 해당 열을 빼서 배열의 위치를 ​​결정하십시오. 음의 열 좌표에서도 작동합니다.

다음과 같이 getter 및 setter에서 맵에 대한 변환을 수행하십시오.

inline function get(q, r) {
    first_column_in_this_row = -floor(q/2);
    return array[r][q - first_column_in_this_row];
}

선택한 좌표 및지도 작업을하려면이를 수정해야합니다 (한 가지 차이점에주의를 기울이십시오). 일부 레이아웃에서는 열 대신 행을 기준으로 열을 오프셋하려고합니다.

동일한 트릭을 사용하여 다른 모양의 맵을 만들 수 있습니다. 사각형에만 국한되지 않습니다.

C 또는 C ++를 사용하는 경우 포인터 산술을 사용하여 더 빠르게 수행 할 수 있습니다. 배열에 대한 포인터 배열을 저장하는 대신에 의해 조정 된 포인터 배열을 저장하십시오 first_column_in_row. (이것은 휴대용이 아닐 수도 있습니다)


이것은 내가 알 수있는 한 작동하지만 수학은 정말 이상했습니다. 내 머리에 의미가있는 몇 가지 방정식을 시도한 yIndex = y-((x%2==0)?(x/2-x):(-x/2)-1)후 시행 착오 후에 정착했습니다 . 어떻게 작동하는지 잘 모르겠습니다.
PeeC

확인하십시오 yIndex = y-((x%2==0)?(-x/2):(-x/2)-1). x / 2는 모두 정수 기반 btw이므로 플로어링 할 필요가 없습니다.
PeeC

6

개인적으로 메모리 절약보다 단순성을 선호합니다. 필요할 때까지 최적화하지 마십시오!

여전히 몇 바이트를 절약하는 데 구부러진 경우 다음과 같이 할 수 있습니다.

여기에 이미지 설명을 입력하십시오

  1. 평행 사변형을 반으로 잘라 두 개의 직각 삼각형을 만듭니다.
  2. 두 삼각형을 재정렬하여 사각형을 만듭니다.
  3. (참고 나는 수학이 잘 작동하도록 녹색 버퍼 스트립을 추가했습니다.)

사각형 좌표를 평행 사변형 좌표에 매핑하는 파이썬 코드 :

# Height of rectangle
H = 15

def r2p(x, y):
"rectangle to parallelogram"
if y < -x/2 + H:
    y = y + H
return (x - 1, y)

def p2r(x,y):
"parallelogram to rectangle"
if y >= H:
    y = y - H
return (x + 1, y)

2
이미지에서 픽셀을 세로로 아래로 이동할 수도 있습니다.offsetY = Math.floor ( (x+1)/2 )
Markus von Broady

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