16

Java で角度を +/- π に正規化するためのライブラリ関数またはよく知られた迅速で効率的な方法はありますか?たとえば、2 つの角度を追加する場合は?

私が今持っているもの(この回答に基づいて)は、基本的に以下のコードです...

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(比較的大きな数ではないことを保証できないことに注意してください%. )

私が使用できる十分にテストされた最適化されたライブラリ関数、またはより優れたアルゴリズムはありますか、それともこれで十分ですか?

4

2 に答える 2

18

Apache commons には次の 1 つがあります。

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 月)最新の commons-math 4.x コードベースから削除されたばかりです。これ以降のバージョンを使用している場合は、(リリースされたら) 代わりにcommons-numbersを使用することをお勧めします- 現在:

a = PlaneAngleRadians.normalizeBetweenMinusPiAndPi(a);

また

a = PlaneAngleRadians.normalize(a, 0.0);
于 2014-06-15T23:07:53.737 に答える
14

100%確実な方法は 1 つだけです。

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

他のすべては、賢くなりすぎて失敗しようとする人々です。

于 2016-03-25T15:09:25.073 に答える