Atan2

提供: testwiki
ナビゲーションに移動 検索に移動

テンプレート:小文字

関数テンプレート:Mathは、点テンプレート:Math方向への半直線(レイ)と、x軸の正の向きとの間の角度テンプレート:Mvarを返す。ただし、範囲はテンプレート:Open-closedである
y/xに関するatan2(y,x)のグラフ

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

関数atan2(y,x)は、プログラミング言語FortranIBM社が1961年に実装したFORTRAN-IV)において最初に登場した。元々は、角度テンプレート:Mvar直交座標系テンプレート:Mathから極座標系テンプレート:Mathに変換する際に、正確で一意な値が返ってくることを意図して導入された。また、atan2(y,x)複素数x+iy偏角テンプレート:Efnを求める際にも利用される。

関数atan2(y,x) は、テンプレート:Mathの範囲で、

x=rcosθy=rsinθ

(ただし、テンプレート:Math)となる単一の値テンプレート:Mvarを返す。

なお、arctanを使って角度テンプレート:Mvarを求める際に注意すべきことであるが、r=x2+y2が真であるからと言って、

θ=arctan(yx)

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

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

関数atan2(y,x)の戻り値である角度テンプレート:Mvarについては、テンプレート:Mvarテンプレート:Mvarの値を変更しないままでも角度テンプレート:Mvarテンプレート:Mathの任意の整数倍を加算することが可能であるため、つまり区間を適切に設定しないと戻り値が曖昧になってしまうため、関数atan2はその主値として、区間をテンプレート:Open-closedとしたものが戻り値として返ってくるようになっている(関数arctanの戻り値の区間が(−テンプレート:Sfrac , テンプレート:Sfrac)である点との違いに注意)。角度テンプレート:Mvar符号付き角度であり、反時計回りの角度は正、時計回りは負となる。具体的は、もしテンプレート:Mathだった場合はテンプレート:Closed-closedの区間にあり、もしテンプレート:Mathだった場合にはテンプレート:Open-openの区間にある、となるように関数atan2(y,x)の内部で場合分けをしている。

atan2が生み出された経緯と動機

テンプレート:独自研究

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

テンプレート:Math関数は、元々は特定のプログラミング言語に実装された関数(サブルーチン)の一つに過ぎなかったが、現在では他の科学技術の分野でもよく使われるものとなっている。その起源は少なくとも、FORTRANATAN2(Y, X)にまで遡ることができ[2]、現代的なプログラミング言語にも標準的な数学関数ライブラリやパッケージの形で実装されている。例を挙げると、C言語およびC++の標準ライブラリ(標準Cライブラリmath.hにおけるatan2()関数あるいは標準C++ライブラリcmathにおけるstd::atan2()関数)、Java標準ライブラリにおけるテンプレート:Javadoc:SEメソッドC#/F#/VB.NETなどから利用できる.NET基本クラスライブラリにおけるSystem.Math.Atan2()メソッド[3]JavaScriptの標準組み込みオブジェクトMath、Pythonのmathモジュール、RubyのMathモジュール、Goのmathパッケージ[4]、などであるが、他にも多数の言語に実装されている。さらに、Perlを始めとするスクリプト言語にも、C言語風のatan2(y, x)関数が実装されていることが多い。

また、単に「便利だから」と言うことも存在の理由の一つである。単一引数のみを取るテンプレート:Math関数(アークタンジェント関数)では正反対の方向を区別できないと言う弱点がある。例えば、テンプレート:Mvar軸とベクトルテンプレート:Mathがなす反時計回りの角度をarctan関数を使って「テンプレート:Math」として計算した場合、「テンプレート:Mathラジアン(度数法でテンプレート:Math)」という答えが返却される。しかし、テンプレート:Mvar軸とベクトルテンプレート:Mathの間の角度を同様に「テンプレート:Math」として計算してみると、期待される返却値は「テンプレート:Mathラジアン(−135°)」または「テンプレート:Mathラジアン(225°)」であるにもかかわらず、「テンプレート:Mathラジアン」が返却される。さらに、テンプレート:Mvar軸とベクトルテンプレート:Mathがなす角度をテンプレート:Math関数で計算しようとするとテンプレート:Mathの評価が必要になってしまい、返却されるのはゼロ除算のエラーとなる。

テンプレート:Math関数は2つの変数 テンプレート:Mvarテンプレート:Mvarから一意なアークタンジェントの値を算出するが、そのとき両変数の正負の符号が実行結果の象限を決定するために利用される。それに基づいて「テンプレート:Math」を実行したときの結果の中から分岐先の結果を選んで返している。例を挙げると、テンプレート:Math関数では同じ結果が返される「テンプレート:Math」 と 「テンプレート:Math」では、入力値の符号を用いてどちらの解を正解と取るのかを判断している。また、例えば前述の「テンプレート:Math」を計算しようとしても、ゼロ除算のエラーの代わりに「テンプレート:Math」を返却することも、同様の方法で行っている。

もちろん、上記の計算を自分で実装すれば極論atan2関数は必要ないが、その実装プログラム中のどこかでミスを犯す危険性がある。それよりも常に一意な正しい結果を返してくれるような関数が存在した方が圧倒的に便利である。そのような経緯からatan2関数が存在するのである。

定義と計算

定義

関数 テンプレート:Math複素数 テンプレート:Math偏角関数 テンプレート:Math を適用した時の主値を計算する。すなわち、テンプレート:Math である。偏角は、テンプレート:Math(原点を中心としたちょうど1周の回転に対応)の整数倍を加えたものも同じ角度になるが、テンプレート:Math を一意に定義するために範囲 (π,π] の主値を使用する。つまり、テンプレート:Math とする。

標準の テンプレート:Math 関数(値域 テンプレート:Open-open)を用いて、次のように表すことができる:

atan2(y,x)={arctan(yx)if x>0,arctan(yx)+πif x<0 and y0,arctan(yx)πif x<0 and y<0,+π2if x=0 and y>0,π2if x=0 and y<0,undefinedif x=0 and y=0.

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

atan2(y,x)={arctan(yx)if x>0,π2arctan(xy)if y>0,π2arctan(xy)if y<0,arctan(yx)±πif x<0,undefinedif x=0 and y=0.

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

atan2(y,x) =arctan(yx)[x0]+sgn(y)(π[x<0]+π2[x=0])
+undefined[x=0y=0] テンプレート:Efn

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

atan2(y,x)=sgn(x)2arctan(yx)+1sgn(x)2(1+sgn(y)sgn(y)2)π

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

atan2(y,x)={2arctan(yx2+y2+x)if x>0 or y0,πif x<0 and y=0,undefinedif x=0 and y=0.

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

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

atan2(y,x)={2arctan(yx2+y2+x)if x>0,2arctan(x2+y2xy)if x0 and y0,πif x<0 and y=0,undefinedif x=0 and y=0.
偏角の主値の導出は、この図を参照している。

注意:

テンプレート:Math のとき テンプレート:Math となる。その結果、次式が成立する。
atan2(y,x)=θ=2θ/2=2arctanyx2+y2+x.
問題の領域は テンプレート:Math であることに注意。

微分

テンプレート:Details 関数 テンプレート:Math は2変数関数であるため、2つの偏導関数がある。これらの導関数が存在する点では、テンプレート:Math は定数項を除いた テンプレート:Math に等しくなる。したがって、テンプレート:Math または テンプレート:Math の場合、

xatan2(y,x)=xarctan(yx)=yx2+y2,yatan2(y,x)=yarctan(yx)=xx2+y2.

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

atan2(y,x)=(yx2+y2, xx2+y2).

関数 テンプレート:Math を角度関数 テンプレート:Math (定数を除いて定義)として省略して表すと、全微分について次の式が得られる:

dθ=xatan2(y,x)dx+yatan2(y,x)dy=yx2+y2dx+xx2+y2dy.

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

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

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

図による可視化

任意の半直線上のatan2

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

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

この図はarctan(tan(θ))と、0θ2πにおけるのatan2(sin(θ),cos(θ))値を示している。両方の関数ともに奇関数であり、それぞれπ2πの周期関数である。このため、θの実数値における補角となることができる。一例としてatan2θ=πにおける分岐截断、およびarctanθ{π2,3π2}における分岐截断が明確に確認できる[5]

下記の2つの図は、テンプレート:Mathおよびテンプレート:Mathの上から見た3次元図である。ここで、テンプレート:MathにおけるX/Y平面の原点から伸びる半直線が定数値なのに対し、テンプレート:MathではX/Y平面の原点を通る直線が定数値である。テンプレート:Mathにおいて、2つの図は同一の値となる。

加法定理

テンプレート:Main article

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

atan2(y1,x1)±atan2(y2,x2)=atan2(y1x2±y2x1,x1x2y1y2)

...ここでatan2(y1,x1)±atan2(y2,x2)(π,π].

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

  1. atan2(y,x)=atan2(y,x) において y0 または x>0.
  2. Arg(x+iy)=atan2(y,x)であり、Arg複素数の偏角の数値計算である。
  3. θ(π,π]である限り、θ=Argeiθが成り立つ(オイラーの公式により)。
  4. Arg(eiArgζ1eiArgζ2)=Arg(ζ1ζ2).

(4)において、複素数の偏角の定理によりeiArgζ=ζ¯、ここで ζ¯=ζ/|ζ|、従って Arg(eiArgζ1eiArgζ2)=Arg(ζ1¯ζ2¯)となる。さらに、全ての正の実数値aに対してArgζ=Argaζが成り立ち、ζ=ζ1ζ2 および a=1|ζ1||ζ2| とすると、Arg(ζ1¯ζ2¯)=Arg(ζ1ζ2)となる。

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

atan2(y1,x1)±atan2(y2,x2)=atan2(y1,x1)+atan2(±y2,x2)by (1)=Arg(x1+iy1)+Arg(x2±iy2)by (2)=Argei(Arg(x1+iy1)+Arg(x2±iy2))by (3)=Arg(eiArg(x1+iy1)eiArg(x2±iy2))=Arg((x1+iy1)(x2±iy2))by (4)=Arg(x1x2y1y2+i(y1x2±y2x1))=atan2(y1x2±y2x1,x1x2y1y2)by (2)

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


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

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

  • atan2(y,x), (東-反時計回り変換)
  • atan2(x,y), (北-時計回り)
  • atan2(x,y). (南-時計回り)

例として、x0=32y0=12の場合、東-反時計回りの場合にはatan2(y0,x0)180π=30、北-時計回りではatan2(x0,y0)180π=60、南-時計回りatan2(x0,y0)180π=120のようになる。

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

プログラミング言語における実装

テンプレート:要改訳 atan2の実装はプログラミング言語ごとに異なる。

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

  • C言語のatan2関数を始めとする多くのプログラミング言語では、直交座標系から極座標系への変換の手間を減らすため、引数は入れ替わったものが使われており、atan2(0, 0)も定義されている。実装においては−0を除外している、あるいは+0が引数に指定された場合には単純にゼロと定義している。関数は常にテンプレート:Closed-closedの間の値を返し、エラーやNaN (Not a Number)を返すことはしない。
  • Common Lispでは引数の数は可変なので、atan関数は1つの場合とx座標を付加した(atan y x)が定義されている。[13]
  • Juliaでは、Common Lispと状況が似ており、atan2の代わりに、1引数形式と2引数形式のatanを持っている[14]。しかし、コンパイル時のアグレッシブな最適化を可能にするため、Juliaはこの2つ以外にも多数のメソッドを持っている[15]テンプレート:Efn
  • Intelアーキテクチャのx87命令では、 atan2FPATAN (floating-point partial arctangent) 命令で実装される。[16]この命令は無限大を扱うことができ、結果は閉区間テンプレート:Closed-closedの値となる。例えば、有限のxに対し、atan2(∞, x) = +テンプレート:Math/2となる。特に両方の引数がゼロである時、FPATANは下記のようになる:
    atan2(+0, +0) = +0;
    atan2(+0, −0) = +テンプレート:Math;
    atan2(−0, +0) = −0;
    atan2(−0, −0) = −テンプレート:Math.
この定義は-0の定義に従ったものとなる。

関連項目

脚注

テンプレート:脚注ヘルプ

注釈

テンプレート:Notelist


出典

テンプレート:Reflist

外部リンク

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