在Java中将角度标准化为+/-π弧度的标准方法

时间:2014-06-15 22:21:01

标签: java radians

在Java中是否存在库函数或众所周知的快速有效方法来将角度标准化为+/-π - 例如添加两个角度时?

我现在所拥有的(基于this answer)基本上是以下代码......

private static final double TWO_PI = 2 * Math.PI;

double normalize(double theta) {
    double normalized = theta % TWO_PI;
    normalized = (normalized + TWO_PI) % TWO_PI;
    return normalized <= Math.PI ? normalized : normalized - TWO_PI;
}

...但它似乎有点复杂且性能明智我对模运算符并不感兴趣。 (注意,我不能保证theta不是一个相对较大的数字,所以我不认为没有循环的纯加法/减法解。我实际上不知道手卷循环是怎样的可能与%进行比较。)

我可以使用经过充分测试的优化库函数,还是更好的算法,或者这样做是否合适?

2 个答案:

答案 0 :(得分:16)

Apache commons有一个:

http://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/org/apache/commons/math3/util/MathUtils.html#normalizeAngle(double, double)

  

将-π和+π之间的角度归一化

     

a = MathUtils.normalizeAngle(a, 0.0);

查看源代码,您可以使用它来重现它(它们使用自己的FastMath.floor但是如果您想在没有外部库的情况下执行它:)

theta - TWO_PI * Math.floor((theta + Math.PI) / TWO_PI)

来源在这里:https://github.com/apache/commons-math/blob/53ec46ba272e23c0c96ada42f26f4e70e96f3115/src/main/java/org/apache/commons/math4/util/MathUtils.java#L107


来自未来读者的注意事项:此方法刚刚(2017年6月)been removed来自最新的commons-math 4.x代码库。如果您在此之后使用的是某个版本,则需要使用commons-numbers代替(一旦发布) - 目前:

a = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(a);

a = PlaneAngleRadians.normalize(a, 0.0);

答案 1 :(得分:7)

只有一种100%万无一失的方式:

public static double normalizeAngle(double angle) {
    return Math.atan2(Math.sin(angle), Math.cos(angle));
}   

其他一切都是人们试图过于聪明和失败。