움직이는 원으로 스윕 된 2D 그리드 셀을 찾는 방법은 무엇입니까?


9

2D 그리드를 기반으로 한 게임을 만들고 있습니다. 일부 셀은 통과 가능하고 일부는 통과 할 수 없습니다. 동적 개체는 그리드와 관계없이 계속 이동할 수 있지만 통과 할 수없는 셀과 충돌해야합니다.

그리드에 대해 광선을 추적하는 알고리즘을 작성하여 광선이 교차하는 모든 셀을 제공합니다. 그러나 실제 객체의 크기는 맞지 않습니다. 나는 현재 그들을 동그라미로 표현하고 있습니다. 그러나 움직이는 원을 추적하는 효과적인 알고리즘을 알 수 없습니다. 필요한 사진은 다음과 같습니다. 여기에 이미지 설명을 입력하십시오

숫자는 원이 그리드 셀과 충돌하는 순서를 나타냅니다. 아무도 이러한 충돌을 찾는 알고리즘을 알고 있습니까? 바람직하게는 C #에서.

업데이트 단일 그리드 셀보다 클 있습니다.


왜 3이 4보다 먼저 충돌합니까?
FxIII

@FxIII 나는 실제로 그림에서 원을 움직 였고, 4 이전에 3을 쳤다.
Nevermind

답변:


6

원의 점에서 이동 방향에 접하는 선을 그리도록 선택했기 때문에 그림이 약간 오도 된 것 같습니다. 원의 상단 및 왼쪽 지점이 가장자리에 닿으면 그리드 가장자리와 충돌하는 것을 알 수 있습니다.

하자 C는 귀하의 중심과 r에 반경 그래서 P ' = C + ( R , 0)과 P " = C + (0, r)을.

경우 D는 당신의 방향 벡터합니다 (versor) 인 두 개의 라인을 가지고 :

R '= D · t + P' ,

R "= D · t + P"

방정식의 선과 그 선의 교차점을 간단히 찾아야합니다.

y = i 와 y = i 는 격자의 가장자리입니다!

이 솔루션은 당신은 발견 할 것이다. 당신은 단순히 X 또는 R의 y 구성 요소 '및 R "을 고려해야하기 때문에 쉽게 t 각 insersection에 대한의 값을, 그리고 thoose의 포인트 t 에 의해 S, 단순히 일종의 그 시점 t 과 끝났습니다.

교차점을 알고 있으면 어떤 셀이 충돌했는지 쉽게 알 수 있다고 생각합니다.

r <1 (셀 너비 및 높이) 인 경우 작동합니다 .

다른 경우에도 간단하게 P 'P " 에 대해 약간의 고려를 합니다. 우리는 방향으로 인해 TOP과 LEFT를 선택합니다. BOTTOM과 RIGHT는 반대 방향으로 고려해야합니다. 이유를 이해해야합니다.

이제이 이미지를보십시오 : 큰 원

원은 단일 셀보다 크며 그림과 같은 방향으로 가고 있다고 가정합니다. P1은 첫 번째 접촉 지점이고, P2는 두 번째 지점이며, P3은 아래쪽 절반에 있으므로 쓸모가 없습니다. 당신이해야 할 일은 앞에서 본 것처럼 P1과 P2에서 광선을 캐스팅하고 수직선에 대해서도 동일하게 수행하는 것입니다.

일반적으로 광선을 쏘는 곳, 원이 클수록 던질 광선이 많을 때 TOP 및 LEFT와 함께 다른 출발점이 있습니다.

솔직히 말해서 어떤 기하학적 고려를하는 모든 광선을 피하는 것은 피할 수 있지만, 이해하기 어렵게 만들 수 있습니다.


그래, 나는 P까지 생각 '및 P "점을 자신 만 원 단일 셀보다 큰 경우 무엇을 알아낼 수 없었다. 추가 점 정말 이해 (내가 분명히에만 광선을 추가 할 필요가 사이에 P'와 P ")
신경 끄시 고

계산을 단순화하는 기하학적 고려를 수행 할 수 있지만 구현을 사용하면 경험에 따라 동일한 결과를 얻을 수 있습니다.
FxIII

가로 및 세로 격자 선을 별도로 테스트해야합니까?
FxIII

원이 모퉁이에서 대각선으로 인접한 셀과 충돌하기 때문에 원이 그리드 정점을 덮을 때도 확인해야하지만 원이 맨 먼저 닿는 원의 맨 위 / 왼쪽 / 맨 아래 / 가장 오른쪽 점은 아닙니다. (충돌을 너무 일찍 감지 할 수 있습니다.) 예 : 문제의 예제 다이어그램에서 제곱 3,4,5입니다. 순서대로 적중하지만 (3, 4, 5) 알고리즘은 4 & 5를 동시에 감지합니다.
finnw

@finnw는 cicle이 이등분선의 방향으로 정확하게 이동하는 경우에만 동시에 접촉합니다.
FxIII

1

광선 충돌 알고리즘을 사용하려면 각 원에서 8 개의 점 (45도 단위로 정사각형 그리드에 정렬)을 선택하고 해당 점 사이에서 광선 충돌을 사용할 수 있습니다 (예 : 하나의 상단부터) 다른 사람의 상단에 동그라미를 치십시오). 이러한 모든 광선 충돌의 합집합은 교차 된 전체 셀 세트입니다.

예를 들어 한 원의 중심에서 다른 원의 중심으로 선분을 사용하지만 원의 반지름으로 평행 선 세그먼트뿐만 아니라 한쪽의 반지름으로 연장되는 선 세그먼트를 사용하여 약간 향상시킬 수 있습니다. 원의 끝에서 양쪽.


8 개의 광선은 아마도 모든 교차점을 보장 할 것이지만, 올바른 순서로 교차점을 제공하지는 않을 것입니다. 그리고 충돌의 경우 셀 목록뿐만 아니라 순서가 필요합니다.
Nevermind

광선 충돌 알고리즘을 보강하여 각 충돌에 대한 t- 값을 유지합니다. 셀 합집합을 얻으면 t- 값을 기준으로 정렬하여 올바른 순서를 얻을 수 있습니다.
TreDubZedd

그러나 다른 광선 의 t- 값을 어떻게 비교할 수 있습니까?
Nevermind

항상 동일한 원에서 시작하는 경우 교차점은 해당 원과의 거리입니다. 이미 본 셀에 왔을 때 현재 충돌의 t- 값이 이전 충돌보다 작 으면 그것을 사용하십시오. 그렇지 않으면 교차점을 버립니다 (원본 유지).
TreDubZedd 2016 년

1
움직임에 수직 인 원의 측면에서 두 개의 광선으로 도망 갈 수 있습니다. 그런 다음 광선에 어떤 타일이 충돌하는지 확인할 수 있으며 나머지는 두 광선 사이에 중심이 있는지 확인할 수 있습니다. 놓칠 수있는 유일한 것은 시작 또는 끝 원에서 충돌하는 것들이지만 두 개의 원일 뿐이므로 쉽게 처리 할 수 ​​있습니다. 8 개의 광선보다 약간 느릴 수 있습니다. 확실하지 않습니다. 그러나 원의 크기에 따라 숫자를 조정할 필요는 없습니다.
Lunin

1

나는 이것이 완벽한 비유라고 말하지는 않지만 Bresenham의 라인 알고리즘에 대해 생각할 수 있습니다 . 이 알고리즘 또는 해당 확장 중 하나를 수정하면 도움이 될 수 있습니다. 특히 다른 게시물 및 댓글과 함께 사용하는 경우에 유용합니다. 일반적 으로이 알고리즘은 순서와 관련이 없지만 상당히 사소하게 추가 할 수 있다고 생각합니다.


나도 이것에 대해 생각하고 있었지만 내 생각에는 이것이 올바른 알고리즘이 아닙니다. Bresenham은 하나의 픽셀 만 선택하므로 모두 필요합니다. 그리고 Bresenham을 단 하나의 픽셀로 원형에 맞추는 것은 어려울 것입니다.
zacharmarz 2016 년

내가 사용하는 광선 추적기는 실제로 Bresenham 알고리즘을 기반으로합니다. 얇은 선에서 "뚱뚱한"선으로, 특히 원을 쓸어 넘기는 것으로 일반화하는 데 어려움이 있습니다.
Nevermind
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.