C ++ 'da atan ve atan2 arasındaki fark nedir?


157

Arasındaki fark nedir atanVe atan2C ++ ?

Yanıtlar:



322

Okul matematiğinden, tanjantın tanımı olduğunu biliyoruz.

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

ve fonksiyonlara verdiğimiz açıya göre dört kadran arasında ayrım yapıyoruz. İşareti sin, cosve tan(biz tam katları ihmal şu ilişki var π/2):

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

Değerinin tan(α)pozitif olduğu göz önüne alındığında , açının birinci veya üçüncü kadrandan olup olmadığını ve negatifse, ikinci veya dördüncü kadrandan gelebileceğini ayırt edemeyiz. Böylece, konvansiyonla, atan()birinci veya dördüncü çeyreğin (yani-π/2 <= atan() <= π/2 tanjantın orijinal girdisine bakılmaksızın ) .

Tam bilgiyi geri almak için bölümün sonucunu kullanmamalıyız, sin(α) / cos(α)ancak sinüs ve kosinüs değerlerine ayrı ayrı bakmalıyız. Ve işte bu atan2(). Hem alır sin(α)ve cos(α)ve ekleyerek tüm dört kadran giderir πsonucunaatan() kosinüs negatif olduğunda.

Not:atan2(y, x) işlevi aslında bir alır yve bir xuzunluğa sahip bir vektör izdüşümüdür bağımsız değişken, vve açı αY- ve x-ekseni, yani

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

bu ilişkiyi verir

y/x = tan(α)

Sonuç: atan(y/x) bazı bilgiler geri tutulur ve sadece girdinin I veya IV çeyreklerden geldiğini varsayabilir. Buna karşılık, atan2(y,x)tüm verileri alır ve böylece doğru açıyı çözebilir.


3
Küçük bir ayrıntı, aralık -π/2 <= atan() <= π/2aslında pi/2kadran II'den bir nokta ( ) içerir .
Z boson

28

Söz gereken başka bir şey olduğunu atan2gibi bir ifade ile teğet hesaplanırken daha kararlıdır atan(y / x)ve x0 veya 0'a yakın olan.


İlginç, bunun için bir kaynağınız var mı? Bu genel olarak mı yoksa sadece C ++ için mi geçerli?
Gerard

26

Gerçek değerler radyan cinsindendir, ancak bunları derece cinsinden yorumlamak şöyle olacaktır:

  • atan = -90 ile 90 arasında açı değeri verir
  • atan2 = -180 ile 180 arasında açı değeri verir

Navigasyonda başlık ve yön gibi çeşitli açıların hesaplanmasını içeren atan2işim için çoğu durumda iş yapar.


12

atan (x) Radyan cinsinden ifade edilen x'in ark tanjantının temel değerini döndürür.

atan2 (y, x) Radyan cinsinden ifade edilen y / x ark tanjantının temel değerini döndürür.

İşaret belirsizliği nedeniyle, bir fonksiyonun, çeyreğin açının sadece teğet değerine (yalnız atanmış) düştüğü kesin olarak belirleyemeyeceğine dikkat edin. Kadranı belirlemeniz gerekiyorsa atan2'yi kullanabilirsiniz.


3
atan2 (x, y) -> atan2 (y, x)
yesraaj

Prensip değerleri aralığıdır (-pi,pi]ancak atan2, aralığa sahiptir, [-pi,pi]bu nedenle for -pinedeniyle başka bir daldan bir ekstra değer içerir . atan2(-0.0,x)x<0
Z boson

4

Sanırım ana soru anlamaya çalışır: "birini ya da diğerini ne zaman kullanmalıyım" ya da "hangisini kullanmalıyım" ya da "Doğru mu kullanıyorum?"

Sanırım önemli nokta sadece zaman-mesafe vektörleri gibi sağa doğru bir yön eğrisinde pozitif değerleri beslemek için tasarlanmıştır atanmıştır. Cero her zaman sol alttadır ve perdeler sadece yukarı ve sağa, sadece daha yavaş veya daha hızlı gidebilir. atan, negatif sayılar döndürmez, bu nedenle sadece sonucunu ekleyerek / çıkararak ekrandaki 4 yöndeki şeyleri izleyemezsiniz.

atan2, başlangıç ​​noktasının ortada olması için tasarlanmıştır ve işler geriye veya aşağı doğru gidebilir. Ekran gösteriminde kullanacağınız şey budur, çünkü eğrinin hangi yöne gitmesini istediğiniz önemli. Böylece atan2 size negatif sayılar verebilir, çünkü cero merkezi ortadadır ve sonucu 4 yönde izlemek için kullanabileceğiniz bir şeydir.


2

Atan2 ile kadranı burada belirtildiği gibi belirleyebilirsiniz .

Kadranı belirlemeniz gerekiyorsa atan2'yi kullanabilirsiniz.


2

Dik açılı bir üçgen düşünün. Hipotenüs r, yatay taraf y ve dikey taraf x etiketlenir. İlgilenilen α açısı x ile r arasındaki açıdır.

C ++ atan2(y, x)bize radyan cinsinden α açısının değerini verecektir. atanyalnızca y ve x ile tek tek değil, y / x ile ilgileniyor veya ilgileniyorsak kullanılır. Eğer p = y / x ise α elde etmek için kullanırız atan(p).

Sen kullanamaz atan2kadranı belirlemek için kullanabileceğiniz atan2yalnızca eğer zaten biliyorsunuz senin içinde kadran hangi! Özellikle pozitif x ve y, birinci kadran, pozitif y ve negatif x, ikincisi vb. atanya da atan2kendileri sadece pozitif ya da negatif bir sayı döndürür, başka bir şey değildir.


4
Eğer sahip olduğunuz p=y/xtek şey hala kullanabilirsiniz atan2(p,1).
Mark Ransom

0

Aşağıdaki Mehrwolf doğrudur, ama işte yardımcı olabilecek bir buluşsal yöntem:

Genellikle ters tanjantın programlanması için olan 2 boyutlu bir koordinat sisteminde çalışıyorsanız, kesinlikle atan2'yi kullanmalısınız. Tam 2 pi açı aralığı verecek ve sizin için x koordinatında sıfırlarla ilgilenecektir.

Bunu söylemenin bir başka yolu da atan (y / x) 'nin neredeyse her zaman yanlış olmasıdır. Atan işlevini yalnızca argüman y / x olarak düşünülemezse kullanın.


0

atan2(y,x)genellikle kartezyen koordinatları kutupsal koordinatlara dönüştürmek istiyorsanız kullanılır. Size açı verirken sqrt(x*x+y*y), varsa veya varsahypot(y,x) size boyut verecektir.

atan(x)bronzluğun tersidir. Sinir bozucu durumda atan(y/x), sisteminiz sağlamadığı için kullanmanız atan2gerekir; xve y, ve için işaretler için ek kontroller yapmanız gerekir.x=0 doğru açıyı elde etmek için.

Not: her iki bağımsız değişkenin de sıfır olduğu durumlar hariç ve atan2(y,x)öğelerinin tüm gerçek değerleri için tanımlanır .yx


0

Atan2 olarak, çıkışı: -pi< atan2(y,x)< pi
ve atan, çıkışı: -pi/2< atan(y/x)< pi/2 // o çeyreği dikkate DEĞİL veya doz.
Eğer aralarında yönünü almak istiyorsanız 0ve 2*pi(lise matematik gibi), biz ATAN2 kullanmaya gerek ve negatif değerler eklemek için 2*piaralarında nihai sonucu elde etmek 0ve 2*pi.
Açıkça açıklamak için Java kaynak kodu şöyledir:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.