web-dev-qa-db-ja.com

atan2()に似たasin2()およびacos2()関数がないのはなぜですか?

私の理解では、出力が-pi/2からpi/2に制限されているため、atan2()自体が常に正しいシータを判別できるとは限らないため、atan()関数はプログラミング言語に存在します。

この場合、同じ問題がasin()acos()の両方に当てはまり、どちらも範囲が制限されているため、asin2()がないのはなぜですか。およびacos2()関数?

11
user4096893

まず、構文はatan(y/x)ではなくatan2(y, x)であり、atan2(y/x)ではないことに注意してください。分割を実行しないことで追加情報、最も重要なのはxyの個々の記号を提供するため、これは重要です。 x座標とy座標が別々にわかっている場合は、象限を含む角度がわかります。

tan(θ) = y/xからsin(θ) = y/sqrt(x²+y²)に移動する場合、逆演算asinysqrt(x²+y²)を取り、それを組み合わせて次のようになります。角度に関するいくつかの情報。ここでは、除算を自分で実行するか、架空の_asin2_関数で処理するかは関係ありません。分母は常に正であるため、分割された引数には、個別の分子と分母に含まれるのと同じ量の情報が含まれます。 (少なくとも、ゼロによる除算が正しく署名された無限大につながるIEEE環境では。)

y座標と斜辺sqrt(x²+y²)がわかっている場合は、角度の正弦はわかりますが、負と正のx値。同様に、x座標と斜辺がわかっている場合は、角度の余弦はわかりますが、y値の符号はわかりません。

したがって、_asin2_と_acos2_は、少なくとも明白な方法では、数学的に実行可能ではありません。ある種の記号が斜辺にエンコードされていれば、状況は異なるかもしれませんが、そのような記号が自然に発生する状況は考えられません。

10
MvG

このように簡単な用語で説明します。
次の説明については、この画像を参照してください。

enter image description here

タスク:範囲全体で正しい角度を追跡する関数を選択します_-180 < θ < 180_

試行1:sin()は、第1象限と第2象限sin(30) = sin(150) = 0.5で正です。 sin()で象限の変化を追跡するのは簡単ではありません。

したがって、asin2()は実行できません。

試行2:cos()は、第1象限と第4象限cos(60) = sin(300) = 0.5で正です。また、cos()で象限の変化を追跡するのは簡単ではありません。

したがって、acos2()は再び実行可能ではありません。

試行3:tan()は、第1象限と第3象限で、興味深い順序で正です。

これは、第1象限で正、第2象限で負、第3象限で正、第4象限で負、ラップアラウンド第1象限で正になります。

tan(45) = 1tan(135) = -1tan(225) = 1tan(315) = -1、およびtan(360+45) = 1など。やあ!象限の変化を追跡できます。

明確な範囲が_-180 < θ < 180_であることに注意してください。また、上記の45度の増分の例では、シーケンスが_1,-1,.._の場合、角度は反時計回りになり、シーケンスが_-1,1,.._の場合、時計回りになります。このアイデアは方向性を解決するはずです。

したがって、atan2()が私たちの選択になります

0
Kay

3D空間でベクトルの回転を行う場合など、「acos2」のような関数が必要になる場合があります。そのような状況では、次のチェックを実行するだけの独自のacos2関数をハードコーディングします。

x_perp=sqrt(x*x+y*y)
r=sqrt(x*x+y*y+z*z)

if(x_perp.gt.0.0d0) then
phi=acos(x/x_perp)
else
phi=0.0d0
endif
if(y.lt.0.0d0) phi=2.0d0*pi-phi
theta=acos(z/r)

ここで、シータとファイは通常の球面座標であり、x、y、zはデカルト座標です。この問題は、yが負の場合に発生し、ファイに位相シフトが必要です。シータにはそのような問題はありません。

0
kotozna

asin(y,x)acos(y,x)はそれぞれatan(y,x)と同じパラメーターを取り、それぞれが同じ答えを与えるからです。それぞれが等しく有効ですが、必要な関数は1つだけです。

不明確さは(atan2の)名前から生じます。その関数は、(正の)x軸を使用して_given x and y, computes the angle_(原点からこの点までの線で作成)します。 angle_from(x,y)のような名前がおそらくより適切だったでしょう。

0
Declan