web-dev-qa-db-ja.com

C ++のatanとatan2の違いは何ですか?

C++のatanatan2の違いは何ですか?

131
yesraaj

std::atan2 は、4つの象限すべてのアークタンジェントを計算できます。 std::atan は、象限1および4からの計算のみを許可します。

109

学校の数学から、接線には定義があることがわかります

tan(α) = sin(α) / cos(α)

関数に供給する角度に基づいて4つの象限を区別します。 sincos、およびtanの符号には、次の関係があります(π/2の正確な倍数を無視します)。

  Quadrant    Angle              sin   cos   tan
-------------------------------------------------
  I           0    < α < π/2      +     +     +
  II          π/2  < α < π        +     -     -
  III         π    < α < 3π/2     -     -     +
  IV          3π/2 < α < 2π       -     +     -

tan(α)の値が正の場合、角度が第1象限か第3象限かどうか、負の場合は第2象限か第4象限かどうかを区別できません。したがって、慣例により、atan()は、タンジェントへの元の入力に関係なく、1番目または4番目の象限(つまり、-π/2 <= atan() <= π/2)から角度を返します。

完全な情報を取得するには、除算の結果sin(α) / cos(α)を使用してはなりませんが、サインとコサインの値を別々に調べる必要があります。これがatan2()の機能です。 sin(α)cos(α)の両方を取り、余弦が負のときはいつでも_atan()の結果にπを追加することで4つの象限すべてを解決します。

備考:atan2(y, x)関数は、実際にyおよびx引数を取ります。これは、長さvおよび角度αのベクトルの射影ですy軸とx軸上、つまり.

y = v * sin(α)
x = v * cos(α)

関係を与える

y/x = tan(α)

結論:atan(y/x)はいくつかの情報を抑制し、入力が象限IまたはIVから来たとのみ想定できます。対照的に、atan2(y,x)はすべてのデータを取得するため、正しい角度を解決できます。

281
Mehrwolf

言及すべきもう1つのことは、atan(y / x)およびxが0または0に近い式を使用して接線を計算する場合、atan2はより安定していることです。

24
Laserallan

実際の値はラジアン単位ですが、度単位で解釈すると次のようになります。

  • atan = -90〜90の角度値を提供します
  • atan2 = -180〜180の角度値を提供します

ナビゲーションの見出しや方位などのさまざまな角度の計算を含む私の作業では、ほとんどの場合、atan2が仕事をします。

23
Keugyeol

atan(x)ラジアンで表されたxのアークタンジェントの主値を返します。

atan2(y、x)ラジアンで表されたy/xの逆正接の主値を返します。

符号のあいまいさのため、関数は角度がタンジェント値(atanのみ)だけでどの象限に入るかを確実に判断できないことに注意してください。象限を決定する必要がある場合は、atan2を使用できます。

10
Roman M

主な質問は、「いつどちらを使用すべきか」、「どちらを使用すべきか」、「正しいものを使用しているか」を把握しようとしていると思います。

重要な点は、atanは、時間距離ベクトルのように、右上がりの方向曲線で正の値を供給することのみを意図したものだと思います。 Ceroは常に左下にあり、thigsは上下にしか移動できません。 atanは負の数を返さないので、結果を加算/減算するだけでは、画面上の4つの方向に物事を追跡することはできません。

atan2は、Originが真ん中にあることを意図しており、物事は後方または下方に進むことができます。これは、画面の表現で使用するものです。曲線をどの方向に移動させたいかは重要だからです。そのため、atan2は負の数を与えることができます。これは、セロが中央にあり、その結果が4方向の追跡に使用できるものだからです。

4
sergio

Atan2を使用すると、 here のように象限を決定できます。

象限を決定する必要がある場合は、atan2を使用できます。

2
Burkhard

直角三角形を考えてみましょう。斜辺r、水平辺yおよび垂直辺xにラベルを付けます。関心角度@は、xとrの間の角度です。

c ++ atan2(y、x)は、角度@の値をラジアンで与えます。 atanは、yとxではなくy/xのみを知っている、または興味がある場合に使用されます。したがって、p = y/xの場合、@を取得するには、atan(p)を使用します。

Atan2を使用して象限を決定することはできません。atan2を使用できるのは、既に知っているどの象限に入っている場合だけです!特に、正のxとyは最初の象限、正のyと負のx、2番目などを意味します。 atanまたはatan2自体は、単に正または負の数を返すだけで、それ以上は何も返しません。

2
bheks

atan2(y,x)は通常、デカルト座標を極座標に変換する場合に使用されます。 sqrt(x*x+y*y)または利用可能な場合はhypot(y,x)がサイズを提供する一方で、角度を提供します。

atan(x)は、単にtanの逆です。面倒な場合は、システムがatan2を提供しないためatan(y/x)を使用する必要があり、xおよびyの兆候について追加のチェックを行う必要があります。 x=0の場合、正しい角度を取得します。

注:atan2(y,x)は、両方の引数がゼロの場合を除き、yおよびxのすべての実数値に対して定義されます。

0
user3303328

Atan2では、出力は-pi <atan2(y,x) <piです。
そしてatanでは、出力は-pi/2 <atan(y/x) <pi/2 //四半期を考慮しません。
02*piの間の向きを取得したい場合(高校の数学など)、atan2を使用する必要があり、負の値には2*piを追加します02*piの間の最終結果を取得します。
これは、それを明確に説明するJavaソースコードです。

System.out.println(Math.atan2(1,1)); //pi/4 in the 1st quarter
System.out.println(Math.atan2(1,-1)); //(pi/4)+(pi/2)=3*(pi/4) in the 2nd quarter

System.out.println(Math.atan2(-1,-1 ));//-3*(pi/4) and it is less than 0.
System.out.println(Math.atan2(-1,-1)+2*Math.PI); //5(pi/4) in the 3rd quarter

System.out.println(Math.atan2(-1,1 ));//-pi/4 and it is less than 0.
System.out.println(Math.atan2(-1,1)+2*Math.PI); //7*(pi/4) in the 4th quarter

System.out.println(Math.atan(1 ));//pi/4
System.out.println(Math.atan(-1 ));//-pi/4
0
user497884

以下のMehrwolfは正しいですが、ここに役立つ発見的方法があります:

逆タンジェントをプログラミングする場合によくある2次元座標系で作業している場合は、間違いなくatan2を使用する必要があります。 2 piの角度範囲全体を提供し、x座標のゼロを処理します。

別の言い方をすれば、atan(y/x)は事実上常に間違っているということです。引数をy/xと見なすことができない場合にのみatanを使用してください。

0
Nick Mulgan