[language-agnostic] 두 각도의 가장 작은 차이

좌표 주위 -PI-> PI 범위에 2 개의 각도가 주어지면 두 각도 중 가장 작은 값은 무엇입니까?

PI와 -PI의 차이는 2 PI가 아니라 0입니다.

예:

중심에서 2 개의 선이 나오는 원을 상상해보십시오. 선 사이에 2 개의 각도가 있습니다. 내부 의 각도는 더 작은 각도 이고 외부의 각도는 더 큰 각도입니다. 합산하면 두 각도가 완전한 원을 만듭니다. 각 각도가 특정 범위 내에 들어갈 수 있다고 가정 하면 롤오버를 고려하여 작은 각도 값은 얼마입니까?



답변

이것은 모든 각도에 대해 서명 된 각도를 제공합니다.

a = targetA - sourceA
a = (a + 180) % 360 - 180

많은 언어에서 modulo오퍼레이션은 피제수와 동일한 부호를 가진 값을 리턴합니다 (예 : C, C ++, C #, JavaScript, 전체 목록 here ). 이를 위해서는 다음 mod과 같은 사용자 정의 기능 이 필요합니다 .

mod = (a, n) -> a - floor(a/n) * n

정도:

mod = (a, n) -> (a % n + n) % n

각도가 [-180, 180] 이내 인 경우에도 작동합니다.

a = targetA - sourceA
a += (a>180) ? -360 : (a<-180) ? 360 : 0

좀 더 장황한 방법으로 :

a = targetA - sourceA
a -= 360 if a > 180
a += 360 if a < -180


답변

x는 목표 각도입니다. y는 소스 또는 시작 각도입니다.

atan2(sin(x-y), cos(x-y))

부호있는 델타 각도를 반환합니다. API에 따라 atan2 () 함수의 매개 변수 순서가 다를 수 있습니다.


답변

두 각도가 x와 y 인 경우 두 각도 사이의 각도 중 하나는 abs (x-y)입니다. 다른 각도는 (2 * PI)-abs (x-y)입니다. 따라서 두 각도 중 가장 작은 값은 다음과 같습니다.

min((2 * PI) - abs(x - y), abs(x - y))

이는 각도의 절대 값을 제공하며 입력이 정규화되었다고 가정합니다 (예 : 범위 내 [0, 2π)).

각도의 부호 (예 : 방향)를 유지하고 범위 [0, 2π)를 벗어난 각도를 허용 하려면 위의 일반화 할 수 있습니다. 다음은 일반화 된 버전의 Python 코드입니다.

PI = math.pi
TAU = 2*PI
def smallestSignedAngleBetween(x, y):
    a = (x - y) % TAU
    b = (y - x) % TAU
    return -a if a < b else b

있습니다 %음의 값이 관여 할 때 운영자가 일부 기호 조정을 포팅하는 것이 필요할 수 있습니다 그렇다면, 특히, 모든 언어에서 동일하게 동작하지 않습니다.


답변

나는 서명 된 답변을 제공 해야하는 도전에 직면합니다.

def f(x,y):
  import math
  return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)


답변

UnityEngine 사용자의 경우 쉬운 방법은 Mathf.DeltaAngle 입니다.


답변

산술 (알고리즘과 반대) 솔루션 :

angle = Pi - abs(abs(a1 - a2) - Pi);


답변

모든 각도와 라디안 및 각도 모두에서 작동하는 C ++의 효율적인 코드는 다음과 같습니다.

inline double getAbsoluteDiff2Angles(const double x, const double y, const double c)
{
    // c can be PI (for radians) or 180.0 (for degrees);
    return c - fabs(fmod(fabs(x - y), 2*c) - c);
}