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);
startPoint
및 endPoint
두 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
그러나 세 번째 제안은 유효합니다.