문제

ATAN2 (y, x)는 180 °에서 불연속성을 가지고 있으며, 여기서 시계 방향으로 전환됩니다 .0 ° ..0 °로 전환합니다.

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

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

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

XY Point Structs의 STARTPOINT 및 ENDPOINT가 주어지면 스 와이프 터치 이벤트의 방향을 계산하고 있습니다. 코드는 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하면 정확히 동일한 숫자를 얻을 수 있습니다. 여기서 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의 모든 조합에 효과가있는 것처럼 보이는 2 가지 솔루션이 있습니다.

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;

대체 솔루션은 다음을 사용하는 것입니다 모드 () 함수로 정의 된 기능 :

function mod(a, b) {return a - Math.floor (a / b) * b;}

그런 다음 다음 기능으로 ini (x, y) 그리고 끝 (x, y) 포인트가 얻어집니다. 각도는 [0, 360] deg로 정규화 된 도로 표현된다. 및 북쪽 참조 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);
    }

r 패키지 지구는 원점과 Easting/Northing이 주어진 일정한 베어링 라인 인 Bearingrhumb을 계산합니다. Easting 및 Northing은 매트릭스 또는 벡터에 있어야합니다. 바람 장미의 원점은 0,0입니다. 다음 코드는이 문제를 쉽게 해결하는 것으로 보입니다.

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도 (-1 + 360) = 359 deg가됩니다.
-179 deg가됩니다 (-179 + 360) = 181 deg

double degree = fmodf((atan2(x, y) * (180.0 / M_PI)) + 360, 360);

이것은 반 시계 반대 방향으로 0 ° -360 °로, 0 °는 3시입니다.

0 ~ 360 도의 값 범위를 갖는 공식.

f (x, y) = 180-90*(1+부호 (x))*(1-sign (y^2)) -45*(2+부호 (x))*부호 (y)

     -(180/pi())*sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top