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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24234609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:59:38  来源:igfitidea点击:

Standard way to normalize an angle to +/- π radians in Java

javaradians

提问by David Moles

Is there a library function or a well-known quick efficient way in Java to normalize an angle to +/- π — e.g. when adding two angles?

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

What I've got now (based on this answer) is basically the code below...

我现在得到的(基于这个答案)基本上是下面的代码......

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

...but it seems a little complicated and performance-wise I'm not excited about the modulo operator. (Note that I can't guarantee thetaisn't some relatively large number, so I don't think there's a pure addition/subtraction solution without looping. I don't actually know how a hand-rolled loop is likely to compare to %.)

...但它似乎有点复杂和性能方面我对模运算符并不感到兴奋。(请注意,我不能保证theta不是某个相对较大的数字,因此我认为没有没有循环的纯加法/减法解决方案。我实际上不知道手动循环与%. )

Is there a well-tested optimized library function I can use, or a better algorithm, or is this as good as it gets?

是否有我可以使用的经过充分测试的优化库函数,或者更好的算法,或者它是否已经足够好?

采纳答案by CupawnTae

Apache commons has one:

Apache Commons 有一个:

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

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

normalize an angle between -π and +π

a = MathUtils.normalizeAngle(a, 0.0);

标准化 -π 和 +π 之间的角度

a = MathUtils.normalizeAngle(a, 0.0);

And looking at the source code, you could reproduce it with this (they use their own FastMath.floorbut in case you want to do it without an external library):

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

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

Source is here: https://github.com/apache/commons-math/blob/53ec46ba272e23c0c96ada42f26f4e70e96f3115/src/main/java/org/apache/commons/math4/util/MathUtils.java#L107

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



Note for readers from the future: this method has just (June 2017) been removedfrom the latest commons-math 4.x codebase. If you're using a version after this, you'll want to use commons-numbersinstead (once it's released) - currently:

未来读者请注意:此方法刚刚(2017 年 6 月)从最新的 commons-math 4.x 代码库中删除。如果您在此之后使用一个版本,您将需要使用commons-numbers代替(一旦发布) - 目前:

a = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(a);

or

或者

a = PlaneAngleRadians.normalize(a, 0.0);

回答by cohadar

There is only one 100% foolproof way:

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

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

Everything else is people trying to be too smart and failing.

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