2010-02-12 4 views
0

특정 방향을 가리키는 게임에 유닛이 있습니다. 다른 방향으로 회전하면 가장 짧은 선회가 가능합니다. 이 계획은 특정 각도에서 시작하고 방향을 향해 선형 (선형 보간)하는 데 필요한 각도를 필요로합니다.게임에서 유닛 회전

예를 들어, 10도에서 350도까지 lerping하면 -10의 목표 각도를 계산해야합니다. 반대로 350에서 10으로 줄이는 것은 370 도의 끝을 계산해야합니다.

이러한 필수 최종 값을 계산할 수있는 알고리즘은 무엇입니까?

편집 : 내가 시간이 지남에 따라 각도를 계산하기 위해 선형 보간법을 사용하고

을 필요 이상 혼란이있는 것 같습니다. 그래서 10에서 20까지 얻고 자한다면 최종 값은 20이어야합니다. 그런 다음 10에서 20까지 보간하여 오른쪽으로 회전합니다. 그러나 마찬가지로 20에서 10으로 가고 싶다면 20에서 10까지 보간법을 반 시계 방향으로 진행하면됩니다. 문제는 시계 방향으로 180도 이상, 270도에서 80도 (210도)가 시계 방향으로 회전해야 할 때, 270에서 80까지의 직선 보간이 반 시계 방향으로 진행될 때 270도에서 420도 (360도 +80), 반 시계 방향으로 진행됩니다.

+0

나는 당신이 말한 것처럼 항상 가장 짧은 차례를 택하려고한다고 가정 할 때, 당신의 예제에 혼란 스럽다. 10 도의 표제를 가지고 있으며 350도까지 회전하고자한다면 -20도 회전입니다. 350 도의 표제를 가지고 있고 10 도가되기를 원한다면 +20도 회전합니다. 내가 놓친 게 있니? –

+0

예, 델타가 아닌 _end 값 _을 계산해야합니다. 10-> 350의 선형 보간은 시계 방향으로 가고, 10-> -10의 선형 보간은 시계 반대 방향으로 바뀝니다. – Martin

+0

일정한 속도를 원하십니까? 거기에 도착할 고정 시간? 델타가있는 경우 각도의 증가분 (일부분)을 사용하고 보간을 시도하지 마십시오. – phkahler

답변

1

당신은 '종료 각도'에 더 집중 뭔가를하려면 어떻게 이것에 대해 :

float startAngle = something, endAngle = something; 

endAngle = ((endAngle - startAngle) % 360) + startAngle; 
if(endAngle < startAngle - 180) endAngle += 360; 
if(endAngle > startAngle + 180) endAngle -= 360; 

이 360

+0

글쎄, 이건 하나의 작품을 확인할 수 있습니다, 그것은 끝 각도를 달성하기 위해 설계된 루프를 사용하지 않습니다 - 내 표를 얻습니다 :) – Martin

4

당신은 범위 -180 ... 180 당신에게 뭔가를 제공

dist = (end - start + 360) % 360; 
if (dist > 180) 
    dist = dist - 360; 

이 필요합니다. 그것이 당신이 원하는 것이라면.

+0

'if (dist <180) dist + = 360;'또 다른 엣지 케이스를 다루기 위해서 ... 'start'는 0이고'end'는 -710입니다. –

+0

이것이 어떻게 문제를 해결하는지 잘 모르겠습니까? 내가 180-> 190에서 lerping하는 경우 내 최종 값을 190으로하고 싶습니다 ... – Martin

+0

방금 ​​전에 내 질문을 업데이트했는데,이 답변을 생각하지 않습니다 (이전에 꽤 불분명했기 때문에) – Martin

1

마틴의 단위로 가능한 startAngle로부터 가까이로 endAngle을 제공합니다, 내 생각 네가 원하는 걸 이해한다. 기본적으로 시작 위치보다 360 ° 더 크게 될 때까지 최종 위치에 360을 추가하면됩니다. 그런 다음 360을 뺍니다. 그것들은 당신의 해결책 일 수있는 두 개의 절대적인 각도입니다. 그렇다면 당신의 대답은 단지 가장 가까운 것입니다.

의사 코드/실제 코드 :

특정 지점을 향해 돌리고 그냥이 프레임 동안 시계 방향 또는 반 시계 방향으로 돌려 여부를 알고 싶은 경우
int current = 350; // where you are now 
int desired = 10; // where you want to go 

while(desired < current) 
    desired += 360; 
int end = desired; 
int start = desired - 360; 

int delta1 = abs(end - current); 
int delta2 = abs(start - current); 
int answer = delta1 < delta2 ? end : current; 
+0

이 모양은 흥미 롭습니다. 나는 이걸로 연극을 할거야 ... – Martin

+0

크리스의 대답은 좀 더 콤팩트하고 우아하고 지금은 (적어도 두 경우를 테스트했을 때) 효과가있다. 나의 접근 방식의 가장 큰 장점은 따라하기 쉽다는 것입니다. 밤늦게까지 지낸다면, 그것을 이해하는데 어려움이 없을 것입니다. 물론, 단위 테스트가 여러 모서리 사례를 통과하도록 설정되어있는 한, 그것을 보지 않아도됩니다. ;) – Dave

0

, 그것을하는 일반적인 방법은 고려하는 것입니다 플레이어의 방향을 벡터로 설정하고 플레이어와 점 사이의 벡터와 벡터 간 교차 곱을 취합니다. 양성이면 반 시계 방향으로 돌립니다. 음수이면 시계 방향으로 돌립니다.