축 정렬 공간 분할 : 공간을 임의의 사각형으로 나눕니 까?


11

3D 공간을 임의의 축 정렬 상자 모양으로 나누는 방법이 필요합니다. 현재 테스트 목적으로 2D 공간을 나누고 있습니다. 내가 찾은 가장 즉각적인 접근 방식은 크기 (1, 1)의 사각형을 정의한 다음 기존의 모든 사각형을 X와 Y 사이를 번갈아 가며 두 개의 고르지 않은 사각형으로 재귀 적으로 분할하는 것입니다.

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

여기서 문제는 명백하다. 이 방법으로 긴 줄이 길게 표시됩니다 (빨간색으로 표시)

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

내가 원하는 것은 더 유기적으로 보이는 것입니다 (예를 포함했습니다)

위쪽에서 아래쪽으로 또는 왼쪽에서 오른쪽으로 긴 직선이 없습니다.

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

유일한 제약은 크기의 입도에 영향을 미치지 않고 사각형의 최소 크기를 제한하고 싶을 수 있습니다. 즉, 가장 작은 rect가 초보다 1 평방 센티미터 인 경우 가장 작은 방은 2 평방 단위가 아니어야합니다.

따라서 이상적으로 알고리즘은 다음 세 가지 제약 조건을 모두 충족해야합니다.

  1. 사각형은 무한히 작지 않습니다.
  2. 사각형 크기는 가장 작은 사각형 크기의 이산 곱셈이 아닙니다. 즉, 가장 작은 rect가 3 square unit보다 큰 rect는 6, 9, 12 등으로 제한되지 않으며 대신에 그 문제에 대해 3.2 또는 4.7이 될 수 있습니다.
  3. 알고리즘은 다항식 시간으로 실행됩니다 (빠른 계산이 필요함).

답변:


12

설명하는 접근 방식은 간단하고 유용하지만 그림과 같이 끔찍한 결과가 발생합니다. 피하십시오. 병렬 성장 알고리즘이 필요합니다. 단일 스레드 모델의 경우 라운드 로빈 접근 방식은 다음과 같습니다.

  1. 지도 공간에 다양한 지점을 무작위로 배치합니다. Voronoi Diagrams의 Lloyd Relaxation 에 따라 가우시안 분포를 사용 하거나 반복 이완 알고리즘을 적용하여 무작위로 배치 된 점을 서로 멀어지게 이동하여 분포를 추산합니다 (추악한 군집 을 피함) . 이 포인트는 객실의 중심을 나타냅니다.
  2. (모든 객실에 대해 병렬 / 반복 라운드 로빈) 각 지점에서 전역 반복마다 중심점에서 4 개의 정점 (직사각형 방)을 자릅니다 (각 축에서 서로 다른 비율로 서로 다른 비율로 성장할 수 있음). 더 유기적이고 다양한 결과가 나올 수 있습니다). 어느 시점에서 일부 사각형이 서로 눌 리기 시작합니다. 이 시점에서 해당 축의 성장을 제한하고 두 방의 인접한 모서리가 정확하게 닿도록하고 계속 진행하십시오.
  3. 인접한 방이나지도 경계에 의해 모든 성장이 제한 될 때까지 2 단계를 반복하여 모든 방을 점진적으로 늘리십시오.
  4. 여전히 빈 공간이 남아 있습니다. 문제는 이제 비 점유 공간에서 방을 찾아서 만드는 것 중 하나가됩니다. 실제로 기본 공간이 (정수 색인) 그리드 (및 모든 성장 반복이 해당 그리드에 스냅) 인 경우 점유 및 비 점유 그리드 셀 목록을 유지할 수 있기 때문에 다루기가 훨씬 쉽습니다. 모든 방을 배치하고 재배 한 경우, 비어있는 목록을 검색하여 인접한 셀 그룹으로 구성된 개별 공간을 찾으십시오. 사용되지 않는 많은 공간이 직사각형이 아닌 모양을 가지므로 직사각형이 아닌 공간 내에서 무작위로 셀을 선택하고 2 단계의 방에서와 마찬가지로 최대 크기로 커야합니다. -완전히 채워질 때까지 직사각형 공간.
  5. 지도가 100 % 점유 될 때까지 4 단계를 반복하십시오.

이것은 좋은 조언입니다. 단점은 무한한 작은 rect로부터 나를 보호하기 위해 아무것도 할 수 없다는 것입니다. 작고 큰 rect가 얼마나 제한되는지 제한 할 방법이 필요합니다. 현재 다른 방법으로 작업하고 있습니다. 결과를 비교하고 업데이트하겠습니다.
AturSams

@ArthurWulfWhite 그런 다음 질문이 잘못 지정되어 업데이트되어야합니다. 최소 객실 크기는지도 셀 해상도에 따라 결정됩니다. 따라서 최소 룸 크기를 수용 할 수있을 정도로 거친 입자를 만들면 부동 소수점을 기준으로 축을 조정하여보다 유기적 인 모양을 얻을 수 있습니다.
엔지니어

당신이 올바른지! 나는 그 부분을 썼다고 생각했다. 그러나 나는하지 않았습니다. 이 실수로 사과드립니다. 예, 그리드 크기를 알고 있습니다. 방은 그리드가 허용하는만큼만 작을 수 있습니다.
AturSams

알겠습니다. 적합한 솔루션을 찾으시기 바랍니다. BTW "축 조정"이 아니라 "그리드 라인 조정"을 의미했습니다.
엔지니어

1
실제로 나는 당신이 생각한 개념을 기반으로 느슨하게 무언가를하고 있습니다. 결과도 여기에 게시하겠습니다.
AturSams

2

보시다시피, 나는이 유물의 세계를 제거했습니다. 아이디어는 매우 비슷합니다.

  1. 2D 공간을 비 균일 그리드로 나눕니다. 두 줄이 너무 가까이 있으면 한 줄을 제거하십시오.
  2. 사각형을 무작위로 선택하고, y 축을 가로 질러 수정되었는지 (높이에서) 직접 이웃이 y 축을 가로 질러 수정되었는지 확인하십시오. 나는 둘 다 수정되지 않았으며, 그들 사이의 세그먼트를 재협상하도록하십시오 (하나는 다른 것에 약간의 공간을 기부 할 것입니다).
  3. 이번에는 다른 축에서 2 단계와 동일하게 수행하십시오.
  4. 가능한 많이 수정하기 전까지 과정을 반복하십시오.

불균일 그리드 (1) :

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

x 축 협상 (2) :

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

y 축 협상 (3) :

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

결과 (4) :

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

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


이 느슨하게 @Nick Wiggill의 통찰력에 의해 고무되었다
AturSams

2
먼저 n * m 개의 인접 셀 그룹을 단일 사각형으로 무작위로 병합하여이를 개선 할 수 있습니다. 위 출력에서 ​​여전히 보이는 기본 그리드를 숨 깁니다. 이 큰 사각형을 사용한 협상은 이제 가장자리 중 하나를 따라 모든 셀에서 작동해야합니다.
DMGregory

확인. 여전히 많은 공선 경계가 있지만 그 이상의 작업을 수행 할 것이지만 솔루션을 찾은 것이 좋습니다! 기꺼이 도와드립니다.
엔지니어

@DMGregory 나는 이것을 고려했지만 작은 rect와 큰 rect 사이의 비율이 다소 일관성이 있기를 원했습니다. 이것이 텍스처 또는 레벨이라면 확실히 할 것입니다 (실제로 이전 예제를 가지고 있습니다).
AturSams

@NickWiggill 공선을 완전히 제거 할 수 있습니다. 알고리즘을 조정하는 것입니다. 더 (가장 최근의 변화와 갱신)을 향상시킬 수있는 방법을이 있어야합니다
AturSams
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.