如何映射ATAN2()到0-360度(How to map atan2() to degrees 0

2019-06-18 16:33发布

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);

我计算给定:起点和终点,既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;
}

Answer 1:

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


Answer 2:

使用模解决方案

一个简单的解决方案,它捕获的所有情况。

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

说明

正:1至180

如果您通过360国防部1和180之间的正数,你会得到你把完全相同的号码。国防部这里只是确保返回的值相同,这些正数。

负:-180到-1

使用MOD,这里将在180名359度的范围内返回值。

特殊情况:0和360

使用返回0 MOD手段,使之成为一个安全的0-359度的解决方案。



Answer 3:

只需添加360°,如果从ATAN2答案是小于0°。



Answer 4:

或者,如果你不喜欢的分支,只是否定了两个参数,并添加180°的答案。

(添加180°的返回值把它很好地在0-360范围内,但翻转角。否定两个输入参数翻转回来。)



Answer 5:

@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度的角度不同。



Answer 6:

我有2个解决方案,似乎正和负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;
}


Answer 7:

@Jason S:你的“FMOD”变种不会对符合标准的实施工作。 C标准是明确的和明确的(7.12.10.1“的FMOD功能”):

如果y为非零值,结果具有相同的符号为x

从而,

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

实际上是只是一个冗长的改写:

atan2(y,x)/M_PI*180

你的第三个建议,但是,即期。



Answer 8:

这就是我通常做:

float rads = atan2(y, x);
if (y < 0) rads = M_PI*2.f + rads;
float degrees = rads*180.f/M_PI;


Answer 9:

angle = Math.atan2(x,y)*180/Math.PI;

我已经作出了式用于定向角成0到360

angle + Math.ceil( -angle / 360 ) * 360;


Answer 10:

一种替代的解决方案是使用MOD()函数定义为:

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

然后,用下面的函数,获得INI(X,Y)结束(X,Y)点之间的角度。 该角度在归一化到[0,360]度表示,该度数。 和北参考360度。

    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);
    }


Answer 11:

的R封装地圈将计算bearingRhumb,其是给定的原点和东/北向的恒定方位线。 的东向和北向必须在一个矩阵或矢量。 对于风玫瑰的原点是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)


Answer 12:

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你
-179你变为(-179 + 360)= 181你



Answer 13:

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

这将从逆时针0°-360°返回度,0°是在3点钟。



Answer 14:

公式来具有的值的范围从0到360度。

F(X,Y)= 180-90 *(1 +符号(X))*(1-符号(Y 2)) - 45 *(2 +符号(X))*符号(y)的

     -(180/pi())*sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))


文章来源: How to map atan2() to degrees 0-360