座標の周りに-PI-> PIの範囲の2つの角度が与えられた場合、それらの間の2つの角度の最小値は何ですか?
PIと-PIの差は2 PIではなくゼロであることを考慮に入れてください。
例:
中心から2本の線が出ている円を想像してください。これらの線の間には2つの角度があり、それらが内側で作る角度は小さい角度、外側が作る角度は大きい角度です。両方の角度を合計すると、完全な円になります。各角度が特定の範囲内に収まる場合、ロールオーバーを考慮して、より小さい角度値は何ですか
座標の周りに-PI-> PIの範囲の2つの角度が与えられた場合、それらの間の2つの角度の最小値は何ですか?
PIと-PIの差は2 PIではなくゼロであることを考慮に入れてください。
例:
中心から2本の線が出ている円を想像してください。これらの線の間には2つの角度があり、それらが内側で作る角度は小さい角度、外側が作る角度は大きい角度です。両方の角度を合計すると、完全な円になります。各角度が特定の範囲内に収まる場合、ロールオーバーを考慮して、より小さい角度値は何ですか
回答:
これにより、任意の角度の符号付き角度が得られます。
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
a -= 360*sgn(a)*(abs(a) > 180)
。(あなたがの無店舗の実装をした場合には、考えてみればsgn
とabs
特性かもしれないが、実際には2回の乗算を必要とする補償するために開始すること、その後、。)
double targetA = 2; double sourceA = 359;
「a」は3.0ではなく-357.0になります
xは目標角度です。yはソースまたは開始角度です。
atan2(sin(x-y), cos(x-y))
符号付きデルタ角度を返します。APIによっては、atan2()関数のパラメーターの順序が異なる場合があることに注意してください。
x-y
角度の違いが得られますが、望ましい範囲外である可能性があります。この角度が単位円上の点を定義していると考えてください。その点の座標は(cos(x-y), sin(x-y))
です。範囲が[-PI、PI]の場合を除いて、そのatan2
ポイントの角度(と同等x-y
)を返します。
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
%
特に負の値が含まれる場合、演算子はすべての言語で同じように動作しないことに注意してください。そのため、移植する場合、いくつかの符号調整が必要になる場合があります。
from math import tau
。
私は署名された答えを提供するという課題に直面します:
def f(x,y):
import math
return min(y-x, y-x+2*math.pi, y-x-2*math.pi, key=abs)
算術(アルゴリズムではなく)ソリューション:
angle = Pi - abs(abs(a1 - a2) - Pi);
ラジアンと度の両方で、あらゆる角度で機能するC ++の効率的なコードは次のとおりです。
inline double getAbsoluteDiff2Angles(const double x, const double y, const double c)
{
// c can be PI (for radians) or 180.0 (for degrees);
return c - fabs(fmod(fabs(x - y), 2*c) - c);
}
三角関数を計算する必要はありません。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);
}
ラジアンでdif = a-bとする
dif = difangrad(a,b);
度単位で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も日焼けもなく、ジオメトリのみ!!!!
arg = arg - PIV2;
はに拡張されarg = arg - M_PI + M_PI
、何も行われません。