[math] atan2 ()를 0-360 도로 매핑하는 방법

atan2(y, x) 180 °에서 시계 방향으로 -180 ° ..0 °로 전환되는 불연속성이 있습니다.

값 범위를 0 ° ..360 °로 매핑하려면 어떻게합니까?

내 코드는 다음과 같습니다.

CGSize deltaPoint = CGSizeMake(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
float swipeBearing = atan2f(deltaPoint.height, deltaPoint.width);

startPointendPoint두 XY 포인트 구조체가 주어지면 스 와이프 터치 이벤트의 방향을 계산하고 있습니다. 코드는 iPhone 용이지만 지원하는 모든 언어가 가능합니다 atan2f().



답변

(x > 0 ? x : (2*PI + x)) * 360 / (2*PI)


답변

모듈로를 사용한 솔루션

모든 경우를 포착하는 간단한 솔루션입니다.

degrees = (degrees + 360) % 360;  // +360 for implementations where mod returns negative numbers

설명

양수 : 1 ~ 180

1과 180 사이의 양수를 360으로 변형하면 입력 한 것과 똑같은 숫자를 얻게됩니다. 여기서 Mod는이 양수가 동일한 값으로 반환되도록합니다.

음수 : -180 ~ -1

여기서 mod를 사용하면 180도에서 359도 범위의 값이 반환됩니다.

특수한 경우 : 0 및 360

mod를 사용하면 0이 반환되어 안전한 0-359도 솔루션이됩니다.


답변

atan2의 답이 0 °보다 작 으면 360 ° 만 추가하면됩니다.


답변

또는 분기가 마음에 들지 않으면 두 매개 변수를 부정하고 답에 180 °를 더하세요.

(반환 값에 180 °를 더하면 0-360 범위에 멋지게 배치되지만 각도가 반전됩니다. 두 입력 매개 변수를 모두 부정하면 다시 반전됩니다.)


답변

@erikkallen은 가깝지만 옳지 않습니다.

theta_rad = atan2(y,x);
theta_deg = (theta_rad/M_PI*180) + (theta_rad > 0 ? 0 : 360);

이것은 C ++에서 작동해야합니다 : (fmod가 구현되는 방법에 따라 조건식보다 빠르거나 느릴 수 있습니다)

theta_deg = fmod(atan2(y,x)/M_PI*180,360);

또는 다음을 수행 할 수 있습니다.

theta_deg = atan2(-y,-x)/M_PI*180 + 180;

(x, y)와 (-x, -y) 각도가 180도 다르기 때문입니다.


답변

양수와 음수 x 및 y의 모든 조합에 대해 작동하는 것으로 보이는 두 가지 솔루션이 있습니다.

1) atan2 () 남용

문서에 따르면 atan2는 매개 변수 y와 x를 순서대로 사용합니다. 그러나이를 되 돌리면 다음을 수행 할 수 있습니다.

double radians = std::atan2(x, y);
double degrees = radians * 180 / M_PI;
if (radians < 0)
{
    degrees += 360;
}

2) atan2 ()를 올바르게 사용하고 나중에 변환하십시오.

double degrees = std::atan2(y, x) * 180 / M_PI;
if (degrees > 90)
{
    degrees = 450 - degrees;
}
else
{
    degrees = 90 - degrees;
}


답변

@Jason S : “fmod”변형은 표준 준수 구현에서 작동하지 않습니다. C 표준은 명확하고 명확합니다 (7.12.10.1, “fmod 함수”) :

y가 0이 아니면 결과는 x와 같은 부호를 갖습니다.

그러므로,

fmod(atan2(y,x)/M_PI*180,360)

실제로는 다음과 같은 장황한 재 작성일뿐입니다.

atan2(y,x)/M_PI*180

그러나 세 번째 제안은 유효합니다.