커브를 이용한 충돌 감지


12

나는 움직이는 원과 어떤 종류의 정적 곡선 (아마도 베 지어 곡선) 사이의 충돌 감지를하고 싶은 2D 게임을 만들고 있습니다.

현재 내 게임에는 정적 지오메트리로 직선만이 있으며 원에서 선까지의 거리를 계산하고 거리가 원 반경보다 작은 경우 원을 선 밖으로 투영하여 충돌 감지를 수행합니다.

이러한 종류의 충돌 감지를 상대적으로 간단하게 수행하려면 어떻게해야합니까? 예를 들어 Box2D에는 베 지어 곡선과의 충돌 감지 기능이 있습니다. 나는 완전한 기능을 갖춘 충돌 감지 메커니즘이 필요하지 않으며, 내가 설명한 것을 할 수있는 것입니다.


업데이트 : 좋은 답변을 주셔서 감사합니다! 위에서 설명한 방법을 완전히 이해하려면 베 지어 곡선을 읽어야합니다. 그럼 다시 연락 드리겠습니다.

답변:


6

29/09/2012-23:20

여기에 git Repo를 만들었습니다 : https://github.com/ArthurWulfWhite/Bezier-Distance/

여기에서 소스 파일을 zip으로 다운로드 할 수 있습니다. FlashDevelop를 사용하여 컴파일 할 수있는 데모도 포함되어 있습니다. 데모를 사용하려면 Flash Develop에서 프로젝트를 열고 '프로젝트 테스트'를 클릭하십시오. 데모를 실행하는 동안 좌 클릭을 클릭하여 새 베 지어 곡선과 새 원을 무작위로 지정하십시오.

행운을 빕니다!

zip 링크는 잘 보이지 않습니다. Ctrl + F를 사용하고 zip을 입력하십시오. 이 소스는 몇 주 동안의 연구와 프로그래밍을 의미합니다.


베 지어를 재귀 적으로 세그먼트로 나누고 충돌을 확인하려는 경우 100,100 배열 (그리드)을 만들고 각 세그먼트를 가장 가까운 네 개의 사각형에 배치하는 것이 좋습니다. 각 프레임을 분할합니다.

프로그래머와 게임 제작자 모두에게 box2d의 이점이 있다고 생각합니다. 모션을 약간 울퉁불퉁하고 유동적으로 보이게하는 '단순한'물리 엔진을 만드는 데 숨겨진 작은 장애물이 많이 있기 때문입니다.

오래된 대답 : 순수한 길.

실제로 원의 중심과 곡선에서 가장 가까운 점 사이의 거리를 확인하여 원이 베 ​​지어 곡선과 충돌하는지 확인할 수 있습니다.

거리에 대한 방정식 (일반)

설명 :

베 지어 방정식 :

q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))

이것은 (대수와 함께) 요약 될 수 있습니다-가독성을 위해. (x, y)를 생략합니다 (여전히 숫자가 아니라 포인트입니다)

q(t) = (start -2 * cont + end) t^2 + (-2 * start + 2 * control) + start

점 (x, y)과의 거리는 다음과 같습니다.

sqrt ((q(t).x - point.x)^2 + (q(t).y - point.y)^2)

베 지어에서 볼에 가장 가까운 점을 찾으려면 도함수가 0 (근) 인 모든 점을 도출하고 찾아야합니다. 3 차 다항식이므로 닫힌 수식을 사용할 수 있지만 컴퓨터 부동 소수점으로 표현 된 분수의 정밀도가 충분하지 않을 수 있으므로 신뢰할 수 없습니다. 뉴턴이나 그 성격의 것을 사용하는 것이 훨씬 좋습니다.

근을 찾아야하는 파생 상품은 다음과 같습니다.

가정 : a = 시작 b = 제어 c = 끝 d = cirlce 중심점

볼프람 알파를 이용한 미분

까다로운 부분은이 점을 곱하는 것이므로 내적을 사용해야합니다.

원하는 경우이 코드가 있으며 충돌 여부와 충돌 각도가 있으면 부울을 반환하는 함수 형태로 여기에서 공유 할 수 있습니다. 이와 같은 충돌 엔진의 순진한 구현에서 일부 문제가 나타날 수 있는데, 예를 들어 빠르게 움직이는 볼이 두 곡선 사이에 끼일 수 있습니다.

지금은 피하는 것이 좋습니다. x 축과 y 축의 계수를 합산하여 합산하십시오.

뉴턴처럼 루트를 찾고 신뢰할 수있는 방법을 사용하여 근을 찾고 베 지어의 근점에서 원 중심까지의 거리를 확인하고 베 지어의 두 끝의 거리를 확인하십시오 (시작 그리고 끝) 가장 가까운 곳의 중심에 충돌이 있는지 알려줍니다.

반경이 최소 거리보다 작은 경우 충돌이 발생합니다.

각도는 대략 원의 중심과 베 지어의 가장 가까운 점 사이의 각도입니다.

즉, 충돌 물리학으로 게임을 만들고 싶다면 베 지어를 반복하는 것이 좋습니다.

    q(t) = (1-t) * ((1-t) * start.(x,y) + t * control.(x,y)) + t*(t * control.(x,y) + (1 - t) * end.(x,y))

중간 크기의 각 조각을 충분히 작아 질 때까지 재귀 적으로 나누고 10 픽셀 이하로 말한 다음 상자에서 대략 베 지어를 만들고 물리학에 Box2d 를 사용 하면이 충돌 감지 코드를 모두 작성할 수 있습니다. 게임 플레이를 많이 향상시키지 않는 시간 싱크. Box2d 사용은 과거 수많은 프로젝트에서 입증되었습니다.


곡선의 가장 짧은 점을 계산하는 방법은 현재 곡선 대신 선으로 사용하는 방법입니다. 그러나 소리를 너무 복잡하게 설명하는 방법으로 곡선에 대해서도 동일하게 수행하십시오. 내가 이해하는 것처럼 당신도 생각합니다. 그리고 Box2D에 관해서. 나는 그것이 훌륭한 일이라고 확신합니다. 그러나 내 게임의 물리학은 솔직히 매우 간단하므로 완전히 풀린 물리 엔진이 과도하다고 결정했습니다.
paldepind

게임에 몇 개의 물건이 있습니까? 얼마나 많은 사람들이 서로 충돌 할 수 있습니까? 때때로 물리 엔진을 사용하면 충돌 시간을 정확하게 계산하는 것과 같은 큰 이점을 얻을 수 있습니다. (프레임이 불연속적이고 충돌이 발생하기 때문에 (프레임을 렌더링 할 때 정확하게 발생하지 않음)
AturSams

새로운 것을 구현할 때 예기치 않은 문제가 발생하고 2D 물리 API를 사용하는 것의 아름다움은 프로그래밍 언어를 사용하는 것과 같으며 학습에 몇 시간을 투자하는 것 외에는 특별한 노력이 필요하지 않습니다. 결과는 매우 만족합니다.
AturSams

지금 몇 가지 세부 정보를 추가했습니다. 행운을 빕니다. :)
AturSams

나는 게임과 같은 간단한 Elasto Mania를 만들고 있습니다. 움직이는 원 3 개와 정적 지오메트리 만 전체 엔진이 완성되어 훌륭하게 작동합니다. 남은 것은이 답변의 도움으로 atm을 해결하려고하는 곡선을 허용하는 것입니다.) 언급 한 코드를 자유롭게 게시하십시오. 실생활에서 사용하는 것이 얼마나 적절하다고 생각하십니까? 베 지어를 작은 선으로 변환하는 것보다 낫습니까?
paldepind

7

이렇게하려면 :

  • 베 지어 곡선을 여러 선 세그먼트로 나누고 저장합니다.

  • 이 모든 세그먼트를 전체 곡선의 축 정렬 경계 상자에 넣습니다.

충돌 감지 :

1) 구가 기본 경계 상자 안에 있는지 확인하십시오. 그렇지 않으면 충돌이 없습니다.

2) 그렇지 않으면 위에서 계산 된 개별 세그먼트가 구와 충돌하는지 확인하십시오. Wikipedia의 Line-sphere 교차 기사를 참조하십시오 .

편집 : 높은 정밀도가 필요하고 좋은 성능을 원한다면 전체 곡선에 대한 기본 경계 상자를 만든 다음 곡선을 두 세그먼트로 나눕니다 (예 : [0.0 - 0.5][0.5 - 1.0]). 각각에 대해 부딩 상자를 생성 한 다음이 두 세그먼트를 다시 두 개의 세그먼트로 세분화하십시오 (따라서 [0 - 0.25], [0.25 - 0.5][0.5 - 0.75], [0.75 - 1.0]). 충분한 정밀도에 도달 할 때까지 이와 같이 계속하십시오. 결국 binary tree에는 주 곡선 경계 상자가 루트에 있고 경계에 선 세그먼트가있는 경계 상자가 있습니다. 트리에서 검색하는 당신에게 준 것 O(log n)대신에 O(n)(여기서 n= 곡선에 대한 선분의 수)


이 솔루션은 나에게 의미가 있으며 이해하기가 가장 쉬우 며 해결해야 할 수도 있습니다. 그러나 더 "순수한"옵션이 존재하는지 궁금합니다.
paldepind

5

선과 베 지어 곡선 사이의 교차점은 곡선을 세분화하여 수학적으로 달성됩니다. 즉, 곡선의 볼록 껍질 특성에 의존하여 제곱 법과 유사한 방식으로 다른 제어 다각형을 사용하여 더 작은 호로 나눕니다.

이 기사는 http://students.cs.byu.edu/~tom/557/text/cic.pdf 까지 다루고 있습니다 .

좋은 점은 알고리즘이 모든 선에서 작동한다는 것입니다. 대상 선이 Ox 축에 평행 한 것으로 간주 할 수 있도록 곡선에 엄격한 변형을 적용하면됩니다.

마찬가지로 베 지어 호를 두 개의 하위 호로 세분화 할 때 이러한 각 베 지어 호의 원과 다각형을 확인할 수 있습니다. 커브-투-원 테스트가 이해 되려면 원이 원호의 제어 다각형과 교차해야합니다.


아직 기사를 읽지 않았습니다. 그러나 선과 베 지어 곡선 사이의 교차점에서 원과 베 지어 사이의 교차점으로 어떻게 이동합니까? 원과 다각형에 대한 충돌을 확인하면 나에게 너무 복잡하게 들립니다.
paldepind
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.