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

两盒软妹~` 提交于 2019-11-30 02:37:55

问题


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?

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 theta isn'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 %.)

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


回答1:


Apache commons has one:

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

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

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


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

a = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(a);

or

a = PlaneAngleRadians.normalize(a, 0.0);



回答2:


There is only one 100% foolproof way:

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.



来源:https://stackoverflow.com/questions/24234609/standard-way-to-normalize-an-angle-to-%cf%80-radians-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!