atan2

出典: フリー百科事典『ウィキペディア(Wikipedia)』
関数atan2(yx)は、点(xy)方向への半直線(レイ)と、x軸の正の向きとの間の角度θを返す。ただし、範囲は(−π,π]である
したときののグラフ

atan2アークタンジェント2)は、関数の一種。「2つの引数を取るarctan(アークタンジェント)」という意味である。x軸の正の向きと、点(xy) (ただし、(0, 0)ではない)まで伸ばした半直線(レイ)との間の、ユークリッド平面上における角度として定義される。関数はもしくはの形をとり、値はラジアンで返ってくる。

関数は、プログラミング言語のFortran (IBM社が1961年に実装したFORTRAN-IV)において最初に登場した。元々は、角度θ直交座標系(xy)から極座標系(rθ)に変換する際に、正確で一意な値が返ってくることを意図して導入された。また、複素数偏角 (「位相」とも言う)を求める際にも利用される。

関数 は、π < θπの範囲で、

(ただし、r > 0)となる単一の値θを返す。

なお、arctanを使って角度θを求める際に注意すべきことであるが、が真であるからと言って、

であるということが常に言えるとは限らない。

これは、x > 0だった場合にのみ当てはまる。もしx < 0だった場合は、上の式から導出された角度は、正しい角度とは正反対の方向を指し示している。そして、デカルト点(xy)をユークリッド平面上の正しい象限に配置するには、(度数法で言うと180°)の値をθに加算または減算する必要がある[1]。これはつまり、正しい角度を出すためにはxおよびyの符号の情報がそれぞれ別個に必要とされると言うことであり、もし単にyxで除算した場合は、その情報が失われてしまうというわけである。その点、atan2は細かいことを気にしなくてもyとxに代入すれば普通に正しい角度を返してくれるので便利である。

関数の戻り値である角度θについては、xyの値を変更しないままでも角度θ2πの任意の整数倍を加算することが可能であるため、つまり区間をちゃんと設定しないと戻り値の値が曖昧になってしまうため、関数atan2はその主値として、区間を(−π, π]としたものが戻り値として返ってくるようになっている(関数arctanの戻り値の区間が(−π/2 , π/2)である点との違いに注意)。角度θ符号付き角度であり、反時計回りの角度は正、時計回りは負となる。具体的に言うと、もしy ≥ 0だった場合は[0, π] の区間にあり、もしy < 0だった場合には(−π, 0)の区間にある、と言う感じになるように関数の内部で場合分けをしている。

atan2が生み出された経緯と動機[編集]

上の図は、角度 θの値が −π から +π までの場合におけるtangent関数(tan θ)のグラフ。その下に示したのは対応するy/x座標の符号である。緑の矢印が指し示しているのは atan2(−1, −1) および atan2(1, 1) の結果(戻り値)である。この図の通り、atan2関数は符号によって場合分けすることで角度θの正しい値を返してくれる。

atan2関数は、元々は特定のプログラミング言語に実装された関数の一つに過ぎなかったが、現在では他の科学技術の分野でもよく使われるものとなっている。その起源は少なくとも、古のプログラミング言語であるFORTRANにまで遡ることができるが[2]、現在においては他の現代的なプログラミング言語においても実装されている。例を挙げると、C言語のmath.h 標準CライブラリJavaのMathライブラリ、.NETのSystem.Math (C#VB.NETなどから利用できる)、Pythonのmathモジュール、RubyのMathモジュール、Goのmathパッケージ[3]、などであるが、もちろん他にもたくさんの言語に実装されている。さらに言うと、Perlを始めとするスクリプト言語にも、C言語風のatan2(y, x)関数が実装されていることが多い。

atan2関数が生み出された背景として、単一引数のみを取るアークタンジェント(arctan関数)は正反対の方向を区別できない、と言う使い勝手の悪さがある。例えば、x軸とベクトル(1, 1)がなす反時計回りの角度を、arctan関数を使って「arctan(1/1)」のような形で計算した場合、「π/4ラジアン(つまり度数法で言うと45°)」という答えが返ってくる。しかし、x軸とベクトル(−1, −1)の間の角度を同様に、「arctan(−1/−1)」のような形で計算してみると、期待される答えは「−3π/4ラジアン(−135°)」または「5π/4ラジアン(225°)」であるにもかかわらず、やっぱり「π/4ラジアン」が返ってくる。arctan関数の使い勝手の悪さをさらに言うと、x軸とベクトル(0, y)(ただし、y ≠ 0とする)がなす角度をarctan関数で計算しようとすると、これはarctan(y/0)の評価が必要になるわけだが、こんなことをさせるとコンピューターはゼロ除算のエラーを吐いてバグる。

atan2関数は、2つの変数 yxから一意なアークタンジェントの値を算出するが、そのとき両変数の正負の符号が、実行結果の象限を決定するために利用される。それに基づいて、アークタンジェントで「y/x」したときの結果の中から、求める値が出るような分岐先に飛ばしている。例を挙げると、「atan2(1, 1) = π/4」 と 「atan2(−1, −1) = −3π/4」のどちらに分岐するのか、と言ったことを判別している。また、例えば「ゼロ除算のエラーを吐いてバグる」の代わりに「atan2(1, 0) = π/2」に分岐させるときも、同様の方法で飛ばしている。

もちろん、場合によって必要な象限補正と例外処理をいちいち精査することで、上記の計算を力技で行うことは可能だが、そんなことをするよりも、常に一意な正しい結果を返してくれるような1つの関数が存在した方が便利である。そんな経緯でatan2関数が存在する。atan2関数は様々な応用(アプリケーション)において有用であり、例えばユークリッド空間上におけるユークリッド点に関して、1つの点から別の点へと至る方向ベクトルを調べるのに便利である。主な用途としては、コンピューターグラフィックス(CG)における回転において、回転行列をオイラー角に変換する際に使われる。

定義と計算[編集]

定義 関数 atan2複素数 x + yi偏角関数 arg を適用した時の主値を計算する。すなわち、atan2(yx) = Pr arg(x + yi) = Arg(x + yi) である。偏角は、(原点を中心としたちょうど1周の回転に対応)の整数倍を加えたものも同じ角度になるが、atan2 を一意に定義するために範囲 の主値を使用する。つまり、π < atan2(yx) ≤ π とする。

標準の arctan 関数(値域 (−π/2, π/2))を用いて、次のように表すことができる:

重複する4つの半平面を用いたコンパクトな式:

アイバーソンの記法を用いれば、さらにコンパクトな式が可能:

[note 1]

一見すると条件式のない数式:

タンジェントの半角の公式から派生した次の式で atan2 を定義することもできる:

この式は、上記の定義よりもシンボリックな使用に適している場合がある。ただし、 の丸め誤差の影響が領域 x < 0, y = 0 の近くで拡大するため、一般的な浮動小数点数の計算用途には適していない(これにより、yがゼロで除算されることもある)。

これらの膨らんだ丸め誤差を回避するため、先ほどの式を変形:

偏角の主値の導出は、この図を参照している。

注意:

  • これにより、範囲 (−π, π] の結果が生成される。[note 2]
  • 上記のように、偏角の主値 atan2(yx) は、三角法によって arctan(y/x) に関連付けることができる。 導出は次のようになる:
(xy) = (r cos θ, r sin θ) のとき tan(θ/2) = y / (r + x) となる。その結果、次式が成立する。
問題の領域は x2 + y2 + x ≠ 0 であることに注意。

微分[編集]

関数 atan2 は2変数関数であるため、2つの偏導関数がある。これらの導関数が存在する点では、atan2 は定数項を除いた arctan(y/x) に等しくなる。したがって、x > 0 または y ≠ 0 の場合、

したがって、atan2 の勾配は次式で与えられる。

関数 atan2 を角度関数 θ(x, y) = atan2(y, x) (定数を除いて定義)として省略して表すと、全微分について次の式が得られる:

関数 atan2 は、負の x 軸に沿って不連続であるが、角度を連続的に定義できないという事実を反映して、この導関数は原点を除いて連続的に定義される。これは、角度の微小な(そして実際には局所的な)変化が原点を除くすべての場所で定義できるという事実を反映している。この導関数をパスに沿って積分するとパス全体の角度が全体的に変化し、閉ループで積分すると回転数が得られる。

微分幾何学の言語では、この導関数は1-形式であり、である(導関数が0である)が、完全ではない(0-形式の導関数、つまり関数ではない)。実際、1点を除いた平面(Punctured Plane)の1次のド・ラームコホモロジーを生成する。これはそのような形式の最も基本的な例であり、微分幾何学の基本である。

atan2 の偏導関数には三角関数が含まれていないため、三角関数の評価にコストがかかる可能性がある多くのアプリケーション(例:組み込みシステム)で特に役立つ。

図による可視化[編集]

任意の半直線上のatan2

この図は、ある半直線に沿ったatan2の値を単位円上に示している。atan2の値はラジアンであり、単位円内に記載されている。標準的な数学の方式に従い、角度は右方向の半直線をゼロとして反時計回りに増加する。ここで、2つの引数の順序が座標と比べて入れ替わっていることに注意が必要である。すなわち、関数atan2(y, x)は座標(x, y)に対応する角度を計算する。

アークタンジェントとatan2関数の比較

この図はと、におけるの値を示している。両方の関数ともに奇関数であり、それぞれの周期関数である。このため、の実数値における補角となることが出来る。一例としてにおける分岐截断、およびにおける分岐截断が明確に確認出来る。[4]

下記の2つの図は、atan2(y, x)およびarctan(y/x)の上から見た三次元図である。ここで、atan2(y, x)におけるX/Y平面の原点から伸びる半直線が定数値なのに対し、arctan(y/x)ではX/Y平面の原点を通る直線が定数値である。x > 0において、2つの図は同一の値となる。

Atan2 diagram.svg Atan diagram.svg

加法定理[編集]

の和は、下記の定理によれば一つの式にまとめることができる。

...ここで.

証明には、 または 、および かつ の二つのケースにわけて行う必要がある。 ここでは前者の または のケースのみにおいて考える。最初に、下記の考察を行う:

  1. において または .
  2. であり、複素数の偏角の数値計算である。
  3. である限り、が成り立つ(オイラーの公式により)。
  4. .

(4)において、複素数の偏角の定理により、ここで 、従って となる。さらに、全ての正の実数値に対してが成り立ち、 および とすると、となる。

上記より、次の等式が成り立つ:

Corollary(推論): もし および が2次元のベクトルであり、これらベクトル間の角度を計算するのに を用いた差分の式が頻繁に用いられているとすると、計算結果はの区間となることから、ほとんどのケースではレンジチェックは不要となる。


東-反時計回り、北-時計回り および 南-時計回り等の変換[編集]

関数は元々数学的に多く用いられる、原点から右の半直線から反時計回りに動く場合の変化について定義している(ここではこれを東-反時計回りと言う)。一方実際の実装系では、北-時計回り および 南-時計回りの変換がよく用いられる。 例えば気象学において、風向関数を用いて、風の東および北向きの成分を引数として利用して計算されている。[5] 同様に太陽の方位角英語版も東および北方向の成分を引数として用いている。風向きは通常北-時計回りで定義されているためであり、太陽の方位角は北-時計回り および 南-時計回り両方を用いて広く計算されていためである。[6] これらの異なる変換は、下記のように位置の置換およびx/y座標の符号を下記のように変更することで実現できる:

  • (東-反時計回り変換)
  • (北-時計回り)
  • . (南-時計回り)

例として、の場合、東-反時計回りの場合には、北-時計回りでは南-時計回りのようになる。

x/y成分の符号の変更と位置の転換は結果として8つのの定義が可能となる。それらは時計回り・反時計回りの4つの方角・東西南北を始点とする。


プログラミング言語における実装[編集]

atan2のプログラミング言語での実装は言語毎に異なる。

入れ替わった順序の引数は下記で用いられている:

  • C言語のatan2関数を始めとする多くのプログラミング言語では、直交座標系から極座標系への変換の手間を減らすため、引数は入れ替わったものが使われており、atan2(0, 0)も定義されている。実装においては−0を除外している、あるいは+0が引数に指定された場合には単純にゼロと定義している。関数は常に[−π, π]の間の値を返し、エラーやNaN (Not a Number)を返すことはしない。
  • Common Lispでは引数の数は可変なので、atan関数は1つの場合とx座標を付加した(atan y x)が定義されている。[12]
  • Juliaでは、Common Lisp同様にatan2関数を定義する代わりに、atanが1つまたは2つの引数を持っている。[13] 1つの関数が複数のメソッドを行う副作用として、コンパイル時の最適化時間が多くなってしまう。[14]
  • Intelアーキテクチャーのアセンブラコードでは、 atan2FPATAN (floating-point partial arctangent) 命令で実装される。[15]この命令は無限大を扱うことができ、結果は閉区間[−π, π]の値となる。例えば、有限のxに対し、atan2(∞, x) = +π/2となる。特に両方の引数がゼロである時、FPATANは下記のようになる:
    atan2(+0, +0) = +0;
    atan2(+0, −0) = +π;
    atan2(−0, +0) = −0;
    atan2(−0, −0) = −π.
この定義は-0の定義に従ったものとなる。
  • コード以外での学術論文などの数学的表記では、通常の arctanおよびtan−1の最初の1文字を大文字にしたArctan[16]およびTan−1[17]が用いられる。用法は複素数の偏角と同様で、Atan(y, x) = Arg(x + iy)となる。
  • シンボリック算術をサポートする実装系では通常、atan2(0, 0) は不定値あるいはエラーを返す。
  • -0無限大NaNをサポートする実装系(例:IEEE 754)では、−π and −0を含む値を返すように拡張されている場合がある。これら実装系では、NaNが入力された時にNaNあるいは例外を返すよう実装されていることも多い。
  • -0をサポートする実装系(例:IEEE 754)では、atan2(y, x)の実装が−0の入力を的確に処理できない場合、atan2(−0, x), x < 0 の時に−πを返すリスクがある。
  • netlibで公開されているフリーの算術ライブラリーであるFDLIBM (Freely Distributable LIBM)では、atan2のソースコードが公開されており、IEEEの例外値の対処方法を確認することができる。
  • ハードウェアによる乗算器を持たない実装系では、atan2関数はCORDIC英語版による数値的に十分な近似により実装されている。よってatan(y)の実装もatan2(y, 1)の実装を用いている場合がある。

参照[編集]

脚注[編集]

[脚注の使い方]

注釈[編集]

  1. ^ 従って
      および、
      (全てのに対し)
  2. ^ 結果の周期性を適用して、別の目的の範囲に写像できる。e.g. 負の結果に を加算すると [0, 2π) に写像できる。

出典[編集]

  1. ^ http://scipp.ucsc.edu/~haber/ph116A/arg_11.pdf
  2. ^ Organick, Elliott I. (1966). A FORTRAN IV Primer. Addison-Wesley. pp. 42. "Some processors also offer the library function called ATAN2, a function of two arguments (opposite and adjacent)." 
  3. ^ src/math/atan2.go”. The Go Programming Language. 2018年4月20日閲覧。
  4. ^ Wolf Jung: Mandel, software for complex dynamics”. www.mndynamics.com. 2018年4月20日閲覧。
  5. ^ Wind Direction Quick Reference, NCAR UCAR Earth Observing Laboratory. https://www.eol.ucar.edu/content/wind-direction-quick-reference
  6. ^ Zhang, Taiping; Stackhouse, Paul W.; MacPherson, Bradley; Mikovitz, J. Colleen (2021). “A solar azimuth formula that renders circumstantial treatment unnecessary without compromising mathematical rigor: Mathematical setup, application and extension of a formula based on the subsolar point and atan2 function”. Renewable Energy 172: 1333–1340. doi:10.1016/j.renene.2021.03.047. 
  7. ^ Microsoft Excel Atan2 Method”. Microsoft. 2022年1月9日閲覧。
  8. ^ LibreOffice Calc ATAN2”. Libreoffice.org. 2022年1月9日閲覧。
  9. ^ Functions and formulas – Docs Editors Help”. support.google.com. 2022年1月9日閲覧。
  10. ^ Numbers' Trigonometric Function List”. Apple. 2022年1月9日閲覧。
  11. ^ ANSI SQL:2008 standard”. Teradata. 2015年8月20日時点のオリジナルよりアーカイブ。2022年1月9日閲覧。
  12. ^ CLHS: Function ASIN, ACOS, ATAN”. LispWorks. 2022年1月9日閲覧。
  13. ^ Mathematics · The Julia Language”. docs.julialang.org. 2022年1月9日閲覧。
  14. ^ Frequently Asked Questions · The Julia Language”. docs.julialang.org. 2022年1月9日閲覧。
  15. ^ IA-32 Intel Architecture Software Developer’s Manual. Volume 2A: Instruction Set Reference, A-M, 2004.
  16. ^ Burger, Wilhelm; Burge, Mark J. (7 July 2010). Principles of Digital Image Processing: Fundamental Techniques. Springer Science & Business Media. ISBN 978-1-84800-191-6. https://books.google.com/books?id=2LIMMD9FVXkC&q=four+quadrant+inverse+tangent+mathematical+notation&pg=PA234 2018年4月20日閲覧。 
  17. ^ Glisson, Tildon H. (18 February 2011). Introduction to Circuit Analysis and Design. Springer Science & Business Media. ISBN 9789048194438. https://books.google.com/books?id=7nNjaH9B0_0C&q=four+quadrant+inverse+tangent+mathematical+notation&pg=PA345 2018年4月20日閲覧。 

外部リンク[編集]

その他のatan2の実装・コード