programing tip

두 각도의 가장 작은 차이

itbloger 2020. 7. 9. 19:25
반응형

두 각도의 가장 작은 차이


좌표 주위 -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 언어의 간단한 코드는 다음과 같습니다.

#include <math.h>
#define PIV2 M_PI+M_PI
#define C360 360.0000000000000000000
double difangrad(double x, double y)
{
double arg;

arg = fmod(y-x, PIV2);
if (arg < 0 )  arg  = arg + PIV2;
if (arg > M_PI) arg  = arg - PIV2;

return (-arg);
}
double difangdeg(double x, double y)
{
double arg;
arg = fmod(y-x, C360);
if (arg < 0 )  arg  = arg + C360;
if (arg > 180) arg  = arg - C360;
return (-arg);
}

라디안으로 dif = a-b하자

dif = difangrad(a,b);

dif = a-b, 각도로 보자

dif = difangdeg(a,b);

difangdeg(180.000000 , -180.000000) = 0.000000
difangdeg(-180.000000 , 180.000000) = -0.000000
difangdeg(359.000000 , 1.000000) = -2.000000
difangdeg(1.000000 , 359.000000) = 2.000000

죄도없고, cos도없고, 황갈색도 없습니다 .... 기하학 만 !!!!


C ++의 효율적인 코드는 다음과 같습니다.

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

참고URL : https://stackoverflow.com/questions/1878907/the-smallest-difference-between-2-angles

반응형