172

座標を中心に -PI -> PI の範囲の 2 つの角度が与えられた場合、それらの間の 2 つの角度の最小値はいくつですか?

PI と -PI の差は 2 PI ではなくゼロであることを考慮してください。

例:

2 本の線が中心から出ている円を想像してみてください。これらの線の間には 2 つの角度があり、内側で作る角度は小さい角度、外側で作る角度は大きな角度です。両方の角度を合計すると、完全な円になります。各角度が特定の範囲内に収まる場合、ロールオーバーを考慮して、角度の小さい方の値はいくつになりますか?

4

9 に答える 9

239

これは任意の角度に対して符号付き角度を与える:

a = targetA - sourceA
a = (a + 180) % 360 - 180

多くの言語では、modulo操作は被除数と同じ符号の値を返すことに注意してください (C、C++、C#、JavaScript、完全なリストはこちらなど)。modこれには、次のようなカスタム関数が必要です。

mod = (a, n) -> a - floor(a/n) * n

とか、ぐらい:

mod = (a, n) -> (a % n + n) % n

角度が [-180, 180] 内にある場合、これも機能します。

a = targetA - sourceA
a += (a>180) ? -360 : (a<-180) ? 360 : 0

より冗長な方法で:

a = targetA - sourceA
a -= 360 if a > 180
a += 360 if a < -180
于 2011-10-23T21:47:40.647 に答える
162

x は目標角度です。y はソースまたは開始角度です。

atan2(sin(x-y), cos(x-y))

符号付きデルタ角度を返します。API によっては、atan2() 関数のパラメーターの順序が異なる場合があることに注意してください。

于 2010-01-05T16:06:36.750 に答える
50

2つの角度がxとyの場合、それらの間の角度の1つはabs(x --y)です。もう1つの角度は(2 * PI)-abs(x-y)です。したがって、2つの角度のうち最小の値は次のようになります。

min((2 * PI) - abs(x - y), abs(x - y))

これにより、角度の絶対値が得られ、入力が正規化されている(つまり、範囲内にある[0, 2π))と想定されます。

角度の符号(つまり方向)を保持し、範囲外の角度も受け入れ[0, 2π)たい場合は、上記を一般化できます。一般化されたバージョンのPythonコードは次のとおりです。

PI = math.pi
TAU = 2*PI
def smallestSignedAngleBetween(x, y):
    a = (x - y) % TAU
    b = (y - x) % TAU
    return -a if a < b else b

%特に負の値が含まれる場合、演算子はすべての言語で同じように動作するわけではないことに注意してください。したがって、移植する場合は、いくつかの符号調整が必要になる場合があります。

于 2009-12-10T06:09:27.423 に答える
9

I rise to the challenge of providing the signed answer:

def f(x,y):
  import math
  return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)
于 2010-01-05T16:19:19.113 に答える
6

UnityEngine ユーザーにとって簡単な方法は、Mathf.DeltaAngleを使用することです。

于 2016-02-07T20:03:30.097 に答える
5

算術 (アルゴリズムではなく) ソリューション:

angle = Pi - abs(abs(a1 - a2) - Pi);
于 2012-03-28T12:07:02.083 に答える
-1

三角関数を計算する必要はありません。C 言語の簡単なコードは次のとおりです。

#include <math.h>
#define PIV2 M_PI+M_PI
#define C360 360.0000000000000000000
double difangrad(double x, double y)
{
double arg;

arg = fmod(y-x, PIV2);
if (arg < 0 )  arg  = arg + PIV2;
if (arg > M_PI) arg  = arg - PIV2;

return (-arg);
}
double difangdeg(double x, double y)
{
double arg;
arg = fmod(y-x, C360);
if (arg < 0 )  arg  = arg + C360;
if (arg > 180) arg  = arg - C360;
return (-arg);
}

let dif = a - b 、ラジアン単位

dif = difangrad(a,b);

let dif = a - b 度単位

dif = difangdeg(a,b);

difangdeg(180.000000 , -180.000000) = 0.000000
difangdeg(-180.000000 , 180.000000) = -0.000000
difangdeg(359.000000 , 1.000000) = -2.000000
difangdeg(1.000000 , 359.000000) = 2.000000

罪なし、cosなし、日焼けなし.... 幾何学だけ!!!!

于 2013-09-27T06:17:20.493 に答える