* 탐색 메쉬 경로 찾기


15

그래서 저는 Greenfoot 이라는이 프레임 워크에서이 하향식 2D 자바 게임을 만들고 있습니다. 저는 여러분이 싸울 사람들을 위해 AI를 연구하고 있습니다. 나는 그들이 현실 세계를 현실적으로 움직일 수 있기를 원하기 때문에 곧 다른 두 가지 중에서도 일종의 길 찾기가 필요하다는 것을 깨달았습니다.

두 개의 A * 프로토 타입을 만들었습니다. 하나는 그리드를 기반 으로 한 다음 웨이 포인트 와 작동하는 것을 만들었 으므로 이제 장애물 / 건물의 2D "지도"에서 경로를 만들 수있는 노드의 그래프로 이동하는 방법을 찾아야합니다. 실제 경로 찾기는 괜찮은 것처럼 보입니다. 열린 목록과 닫힌 목록만이보다 효율적인 데이터 구조를 사용할 수는 있지만 필요할 때 필요할 때 얻을 수 있습니다.

ai-blog.net 의이 게시물에 나와있는 모든 이유로 내비게이션 메시를 사용하려고합니다 . 그러나 내가 직면 한 문제는 A *가 다각형 중심 / 가장자리에서 가장 짧은 경로라고 생각하는 것이 노드의 일부를 통과하는 경우 반드시 최단 경로가 아니라는 것입니다. 더 나은 아이디어를 얻으려면 stackoverflow 에서 질문 한 내용을 볼 수 있습니다 .

가시성 그래프에 관한 좋은 대답을 얻었습니다. 그 이후로 나는 책 ( Computational Geometry : Algorithms and Applications )을 구입하여 주제를 자세히 읽었지만 여전히 탐색 메쉬를 선호하고 있습니다 ( Amit 's Notes에서 Path-Finding에 대한 " 복잡성 관리 " 참조 ). (부수적으로, 첫 번째와 마지막이 가려지지 않은 경우 Theta *를 사용하여 여러 웨이 포인트를 하나의 직선으로 변환 할 수 있습니다. 또는 마지막으로 돌아갈 때마다 마지막으로 웨이 포인트로 이동하여 이것에)

따라서 기본적으로 내가 원하는 것은 일단 깔때기 알고리즘 (예 : Digesting Duck 의이 알고리즘)을 통해 일단 탐색하면 탐색 노드입니다. 그러나 일부 다각형을 통과하고 노드 / 가장자리를 건너 뛸 수 있다는 점을 감안하면 실제로 가장 짧지는 않습니다.

아 그리고 나는 다각형에 관한 정보를 저장하는 방법을 알고 싶습니다. 웨이 포인트 프로토 타입 예제의 경우 각 노드를 객체로 만들고 해당 노드에서 이동할 수있는 다른 모든 노드의 목록을 저장했습니다. 폴리곤에서는 작동하지 않을 것 같습니다. 다각형이 열려 있거나 통과 가능한지 또는 단단한 물체인지 어떻게 알 수 있습니까? 다각형을 구성하는 노드를 어떻게 저장합니까?

마지막으로, 기록을 위해 : 이미 사용할 수있는 다른 솔루션이 있지만이 게임 이외의 다른 코드 에서이 코드를 사용하려고하지 않기 때문에 처음부터 직접 프로그래밍하고 싶습니다. 필연적으로 품질이 떨어질 것입니다.


확실하지 않지만 이러한 링크가 도움이 될 수 있습니다. gamedev.stackexchange.com/questions/1327/… gamedev.stackexchange.com/questions/8087/… 또한 찾을 수없는 경로 찾기에 대한 또 다른 질문이 있습니다. 현상금을 받고 매우 좋은 답변을 받았습니다.
Ali1S232

예, 두 번째 링크에서 내 주요 관심사를 볼 수 있습니다 .A * 알고리즘은 가장자리 중간 점을 사용하여 가장 짧은 경로로 하단 경로를 제공하지만 장애물 상단의 경로는 실제로 가장 짧습니다. 나는 A *를 통해 경로를 둥글게 만들 수있는 방법을 알고 싶습니다. 예를 들어 깔때기 알고리즘으로) 가장 짧은 경로를 얻습니다. 내가 똑바로해도 여전히 우회하고 있습니다.
angrydust

실제로 나는 gamedev.stackexchange.com/questions/8087/ 의 기사를 읽었 으며 A *로 경로를 찾은 다음 수정 된 깔때기 알고리즘으로 실제 비용을 계산 한 다음 다른 경로를 찾아 계산하는 것이 효과가있는 것 같습니다. 다시 비용을 지불하고 다른 것보다 짧은 지 확인하십시오. 가장 짧은 경로를 찾을 때까지 반복됩니다. 이것은 실제로 내 문제를 해결하지만 직선화와 경로 찾기를 반복하면 상당히 느려질 것 같습니다.
angrydust

다각형 저장 : 보이는 다각형 만 저장하거나 태그를 각 다각형과 연결합니다 (각 다각형은 꼭짓점의 원형 목록이어야 함을 기억하십시오). 마찬가지로 노드를 사용하여 원래 다각형의 ID를 저장할 수 있습니다. 그러나 기본 데이터 저장소라는 것을 말할 필요는 없습니다. 마지막으로 당신은 왜합니까 신경 진정한 최단 경로에 대해? 게임 속도가 느리거나 경로가 약간 틀릴 수 있습니다. 하나를 선택하십시오. 실제 최단 경로를 얻으려면 전체 너비 우선 검색이 필요 합니다 (적어도 노드 그래프 이상).
Jonathan Dickinson

@JonathanDickinson 나는 마지막 픽셀에 100 % 정확한 경로가 필요하지 않다는 것을 알고 있으며 A *를 사용하여 최대 p 허용 가능한 경로를 만들 수 있다는 것을 알고 있습니다 . 스택 오버플로 또는 gamedev.stackexchange.com/questions/8087/… 에 대한 이전 질문 에서와 같이 문제 는 장애물을 극복하기 위해 먼 길을 가고 있습니다. AI가 장애물을 따라 걸어 다닐 수는 없습니다!
angrydust

답변:


14

모든 코드를 작성하려고하더라도 생성 된 navmesh를 보여주는 시각화 기능이있는 Recast를 다운로드하고 샘플 애플리케이션을 빌드하고 간단한 포인트로 클릭하여 경로 찾기를 테스트 할 수 있다고 조언합니다. 상호 작용. 그걸 가지고 노는 것만으로도 많은 것을 배울 수 있습니다.

이미 알고 있듯이, A * 경로 파인더와 경로 교정 (장애물을 피하기 위해 필요하지 않은 회전 제거)을 포함하는 후속 후 처리와 같이 잘 보이는 경로를 생성하는 두 단계가 있습니다. 전환점에서 커브 추가.

길 찾기

당신은 A * 부분을 마스터했습니다. 또한 A *가 항상 가장 정확한 경로를 찾을 수는 없다는 것을 관찰했습니다. A *는 그래프를 메시에 적용 할 때 그래프를 통해 최단 경로를 찾는 알고리즘 (노드가 차원이없는 수학적 개념이기 때문에)이므로 노드를 메시 요소에 매핑해야한다는 점을 이해하는 것이 중요합니다.

가장 확실한 방법은 다각형 중심점에서 중심점으로 이동하여이 거리를 기준으로 비용을 계산하는 것이지만 몇 가지 문제가 있습니다. 하나는 항상 기하학적으로 가장 짧은 경로를 찾을 수 없다는 것입니다. 두 번째는 계산 한 경로를 따라 가려고하면 한 중심에서 다른 중심으로 직선이 다음과 같은 다각형을 통과 할 수 있다는 것입니다 경로의 일부가 아니며 탐색 할 수 없을 수도 있습니다. A *를 수행하는 동안 그래프 순회 비용을 지불하는 끔찍한 방법은 아니지만 순회 목적에는 적합하지 않습니다.

다음으로 가장 간단한 해결책은 메쉬를 통해 가장자리에서 가장자리까지 A *를 수행하는 것입니다. 다각형 당 하나의 노드 대신 다각형 당 하나의 모서리가 있다고 생각하면이 생각을 간단하게 할 수 있습니다. 따라서 경로는 시작점에서 가장 가까운 가장자리 안쪽으로 이동하고 인접한 다각형의 가장자리 안쪽으로 교차 한 다음 같은 다각형의 다음 가장자리 안쪽으로 교차합니다. 이렇게하면 가장 짧은 경로가 더 자주 생성되고 경로 교정 단계를 수행하지 않으려는 경우 통과 할 수 있다는 이점이 있습니다.

경로 교정

Detour (Recast와 함께 제공되는 탐색 라이브러리)에서 사용되는 알고리즘은 매우 간단합니다. A * 검색 중에 찾은 다각형의 경계 내에서만 경로가 직선화됨을 관찰해야합니다. 따라서 장애물 주변에서 가장 빡빡한 경로를 찾지 못하면 해당 알고리즘을 실행 한 후에도 빡빡한 경로를 얻지 못합니다. 실제로 리 캐스트에 의해 생성 된 내비 메시는 초크 포인트 (두 장애물 사이의 가장 가까운 포인트)를 탐색 할 때 통과 할 수있는 단일 다각형을 갖는 경향이 있으므로 A *는 항상 장애물에 가까운 노드 목록을 생성합니다 가능한. 타일을 navmesh로 사용하는 경우에는 해당되지 않으며이 매우 간단한 알고리즘은 가짜 회전을 삽입합니다.

회전을 삽입해야한다고 판단하면 깔때기를 왼쪽으로 마지막으로 조인 지점 (왼쪽으로 회전 할 때와 반대 방향으로)에 삽입하기 때문에 Detour의 경로 교정 알고리즘은 그다지 복잡하지 않습니다. 그런 다음 해당 지점에서 노드를 다시 추적하기 시작합니다.

A * 경로의 일부를 형성하는 다각형 외부의 경로를 직선화하려는 경우 상황이 훨씬 더 복잡해집니다. navmesh의 두 점이 서로를 볼 수 있는지 테스트 할 수있는 레이트 캐스트 루틴을 구현해야합니다 (어쨌든 A *를 사용해야하는지 확인할 수 있습니다). 원점-> 대상에 의해 형성된 선분을 원점이 포함 된 다각형의 연결 모서리와 교차시킨 다음 다각형의 연결 모서리를 테스트하는 등의 작업을 수행합니다. 비 연결 모서리를 교차 시키면 (가장자리 모서리라고 함) 장애물에 부딪힌 것입니다.

그런 다음 깔때기 알고리즘이 실제로 삽입 여부를 확인하기 위해 회전을 삽입해야한다고 결정할 때 마다이 레이 캐스트 테스트를 수행 할 수 있지만 회전을 삽입 할 때까지 모든 노드에서 해당 테스트를 계속 수행해야한다고 생각합니다 ( 간단한 퍼널 알고리즘으로 되돌릴 수 있습니다). 약 O (n ^ 2)를 곧게 펴는 경로를 렌더링하면 비용이 많이 듭니다.

내비 메시 표현

메쉬를 다각형 클래스의 배열로 나타낼 수 있습니다. 다각형 클래스는 꼭지점 배열과 각 모서리에 대해 인접한 다각형에 대한 참조 배열 (있는 경우)만큼 간단 할 수 있습니다. 물론 더 컴팩트하게 저장하는 방법을 생각할 수 있습니다. 정점은 일반적으로 여러 다각형에 의해 공유되므로 하나의 큰 정점 배열을 갖는 다음 각 다각형이 해당 배열에 색인을 저장하는 것이 일반적입니다. navmesh의 특성에 따라 가장자리 수의 50 % 이하인 평균 연결 가장자리 수가있을 수 있습니다. 이 경우 모든 모서리에 대한 링크를 저장하는 대신 다른 다각형에 대한 링크와 모서리의 색인을 저장하려고 할 수 있습니다. 또한 클래스 참조를 사용하는 대신 다각형 인덱스를 navmesh의 다각형 배열에 저장하는 것이 좋습니다.


나는 이것에 대해 간단히 읽었지만 A *에 대해 거리의 제곱 (또는 제곱근이 아님)을 사용해서는 안된다는 것을 이해합니다 : theory.stanford.edu/~amitp/GameProgramming/…
angrydust

실제로 경로 교정 atm에 대해 실제로 고민하는 방법에 대해서는 신경 쓰지 않습니다. 제가 걱정하는 것은 "A * 검색 중에 발견 된 다각형의 경계 내에서만 경로를 곧게 할 것입니다. 따라서 장애물 주변에서 가장 빡빡한 경로를 찾지 못하면 해당 알고리즘을 실행 한 후에도 빡빡한 경로를 얻지 못할 것입니다. "
angrydust

정점 / 중간 점을 통한 여행 비용에 관계없이 A *가 항상 직선화 된 경로가 가장 짧은 경로를 찾을 수있는 탐색 메쉬를 갖고 싶습니다. 가시성 그래프를 사용 하여이 작업을 수행 할 수 있음을 높이 평가하지만 다른 이점이 많고 가시성 그래프의 복잡성이 매우 빠르게 커질 수 있기 때문에 navmesh를 사용하고 싶습니다
angrydust

@theguywholikeslinux는 유클리드 거리를 사용할 수 sqrt(x*x + y*y)있지만 노드 당 저렴한 것은 아닙니다 x*x + y*y.
Jonathan Dickinson

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