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);
startPoint와 endPoint (둘 다 XY 포인트 구조체)가 주어지면 스 와이프 터치 이벤트의 방향을 계산하고 있습니다. 코드는 iPhone 용이지만 atan2f ()를 지원하는 모든 언어가 가능합니다.
일반 솔루션과 코드 모두에 대한 도움을 주셔서 감사합니다.
업데이트 : erikkallen의 대답을 멋진 긴 변수 이름을 가진 함수로 만들었으므로 지금부터 6 개월 후에 이해할 것입니다. 아마도 다른 iPhone 멍청이를 도울 것입니다.
float PointPairToBearingDegrees(CGPoint startingPoint, CGPoint endingPoint)
{
CGPoint originPoint = CGPointMake(endingPoint.x - startingPoint.x, endingPoint.y - startingPoint.y); // get origin point to origin by subtracting end from start
float bearingRadians = atan2f(originPoint.y, originPoint.x); // get bearing in radians
float bearingDegrees = bearingRadians * (180.0 / M_PI); // convert to degrees
bearingDegrees = (bearingDegrees > 0.0 ? bearingDegrees : (360.0 + bearingDegrees)); // correct discontinuity
return bearingDegrees;
}
(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
그러나 세 번째 제안은 유효합니다.
이것은 내가 일반적으로하는 일입니다.
float rads = atan2(y, x);
if (y < 0) rads = M_PI*2.f + rads;
float degrees = rads*180.f/M_PI;
angle = Math.atan2(x,y)*180/Math.PI;
각도를 0에서 360으로 맞추는 공식을 만들었습니다.
angle + Math.ceil( -angle / 360 ) * 360;
다른 해결책은 다음과 같이 정의 된 mod () 함수 를 사용하는 것입니다.
function mod(a, b) {return a - Math.floor (a / b) * b;}
Then, with the following function, the angle between ini(x,y) and end(x,y) points is obtained. The angle is expressed in degrees normalized to [0, 360] deg. and North referencing 360 deg.
function angleInDegrees(ini, end) {
var radian = Math.atan2((end.y - ini.y), (end.x - ini.x));//radian [-PI,PI]
return mod(radian * 180 / Math.PI + 90, 360);
}
The R packages geosphere will calculate bearingRhumb, which is a constant bearing line given an origin point and easting/northing. The easting and northing must be in a matrix or vector. The origin point for a wind rose is 0,0. The following code seems to readily resolve the issue:
windE<-wind$uasE
windN<-wind$vasN
wind_matrix<-cbind(windE, windN)
wind$wind_dir<-bearingRhumb(c(0,0), wind_matrix)
wind$wind_dir<-round(wind$wind_dir, 0)
theta_rad = Math.Atan2(y,x);
if(theta_rad < 0)
theta_rad = theta_rad + 2 * Math.PI; //if neg., add 2 PI to it
theta_deg = (theta_rad/M_PI*180) ; //convert from radian to degree
//or
theta_rad = Math.Atan2(y,x);
theta_rad = (theta_rad < 0) ? theta_rad + 2 * Math.PI : theta_rad;
theta_deg = (theta_rad/M_PI*180) ;
-1 deg becomes (-1 + 360) = 359 deg
-179 deg becomes (-179 + 360) = 181 deg
double degree = fmodf((atan2(x, y) * (180.0 / M_PI)) + 360, 360);
This will return degree from 0°-360° counter-clockwise, 0° is at 3 o'clock.
A formula to have the range of values from 0 to 360 degrees.
f(x,y)=180-90*(1+sign(x))* (1-sign(y^2))-45*(2+sign(x))*sign(y)
-(180/pi())*sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
참고URL : https://stackoverflow.com/questions/1311049/how-to-map-atan2-to-degrees-0-360
'development' 카테고리의 다른 글
문자열이 비어 있으면 일부 기본값을 반환합니다. (0) | 2020.09.04 |
---|---|
arm64 아키텍처에 대한 중복 기호 (0) | 2020.09.04 |
Eclipse 가져 오기를위한 키 단축키 (0) | 2020.09.04 |
div가 자바 스크립트와 함께 존재하지 않는지 확인하십시오. (0) | 2020.09.04 |
개인 메서드의 단위 테스트 (0) | 2020.09.04 |