Apa perbedaan antara atan dan atan2 dalam C ++?


157

Apa perbedaan antara atandan atan2di C ++?

Jawaban:



322

Dari matematika sekolah kita tahu bahwa garis singgung memiliki definisi

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

dan kami membedakan antara empat kuadran berdasarkan sudut yang kami suplai ke fungsi. Tanda dari sin, cosdan tanmemiliki hubungan berikut (di mana kita mengabaikan kelipatan persis π/2):

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

Mengingat bahwa nilai tan(α)positif, kita tidak dapat membedakan, apakah sudutnya dari kuadran pertama atau ketiga dan jika negatif, itu bisa berasal dari kuadran kedua atau keempat. Jadi dengan konvensi, atan()mengembalikan sudut dari kuadran pertama atau keempat (yaitu -π/2 <= atan() <= π/2), terlepas dari input asli ke garis singgung.

Untuk mendapatkan kembali informasi lengkap, kita tidak boleh menggunakan hasil pembagian sin(α) / cos(α)tetapi kita harus melihat nilai-nilai sinus dan kosinus secara terpisah. Dan inilah yang atan2()dilakukannya. Dibutuhkan keduanya, the sin(α)dan cos(α)dan menyelesaikan keempat kuadran dengan menambah πhasil atan()setiap kali kosinus negatif.

Keterangan: The atan2(y, x)fungsi sebenarnya mengambil ydan xargumen, yang merupakan proyeksi dari vektor dengan panjang vdan sudut αpada y dan sumbu x, yaitu

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

yang memberi relasi

y/x = tan(α)

Kesimpulan: atan(y/x) menahan beberapa informasi dan hanya dapat berasumsi bahwa input berasal dari kuadran I atau IV. Sebaliknya, atan2(y,x)dapatkan semua data dan dengan demikian dapat menyelesaikan sudut yang benar.


3
Satu detail kecil, kisaran -π/2 <= atan() <= π/2sebenarnya mencakup satu titik ( pi/2) dari kuadran II.
Z boson

28

Satu hal lagi yang atan2lebih stabil ketika menghitung garis singgung menggunakan ekspresi like atan(y / x)dan x0 atau mendekati 0.


Menarik, apakah Anda memiliki sumber untuk ini? Apakah ini benar secara umum atau hanya untuk C ++?
Gerard

26

Nilai aktual dalam radian tetapi untuk menafsirkannya dalam derajat itu akan:

  • atan = memberikan nilai sudut antara -90 dan 90
  • atan2 = memberikan nilai sudut antara -180 dan 180

Untuk pekerjaan saya yang melibatkan perhitungan berbagai sudut seperti pos dan bantalan navigasi, atan2dalam banyak kasus melakukan pekerjaan.


12

atan (x) Mengembalikan nilai utama dari garis singgung x, yang dinyatakan dalam radian.

atan2 (y, x) Mengembalikan nilai utama dari tangen arc dari y / x, dinyatakan dalam radian.

Perhatikan bahwa karena ambiguitas tanda, suatu fungsi tidak dapat menentukan dengan pasti di mana kuadran sudut jatuh hanya oleh nilai tangennya (atan saja). Anda dapat menggunakan atan2 jika Anda perlu menentukan kuadran.


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

Rentang nilai prinsip (-pi,pi]tetapi atan2 memiliki rentang [-pi,pi]sehingga mencakup satu nilai tambahan -pidari cabang lain karena atan2(-0.0,x)untuk x<0.
Z boson

4

Saya kira pertanyaan utama mencoba untuk mencari tahu: "kapan saya harus menggunakan satu atau yang lain", atau "yang harus saya gunakan", atau "Apakah saya menggunakan yang benar"?

Saya kira poin pentingnya adalah atan hanya dimaksudkan untuk memberi makan nilai positif dalam kurva arah kanan-atas seperti untuk vektor jarak-waktu. Cero selalu di kiri bawah, dan thig hanya bisa naik dan ke kanan, lebih lambat atau lebih cepat. atan tidak mengembalikan angka negatif, jadi Anda tidak dapat melacak hal-hal di 4 arah pada layar hanya dengan menambahkan / mengurangi hasilnya.

atan2 dimaksudkan untuk asal berada di tengah, dan hal-hal bisa mundur atau turun. Itulah yang akan Anda gunakan dalam representasi layar, karena itu TIDAK peduli ke arah mana Anda ingin kurva pergi. Jadi atan2 dapat memberi Anda angka negatif, karena cero-nya ada di tengah, dan hasilnya adalah sesuatu yang dapat Anda gunakan untuk melacak hal-hal di 4 arah.


2

Dengan atan2 Anda dapat menentukan kuadran seperti yang dinyatakan di sini .

Anda dapat menggunakan atan2 jika Anda perlu menentukan kuadran.


2

Pertimbangkan segitiga siku-siku. Kami memberi label pada sisi miring r, sisi horizontal y dan sisi vertikal x. Sudut bunga α adalah sudut antara x dan r.

C ++ atan2(y, x)akan memberi kita nilai sudut α dalam radian. atandigunakan jika kita hanya tahu atau tertarik pada y / x bukan y dan x secara individual. Jadi jika p = y / x maka untuk mendapatkan α kita akan gunakan atan(p).

Anda tidak dapat menggunakan atan2untuk menentukan kuadran, Anda dapat menggunakan atan2hanya jika Anda sudah tahu di kuadran mana Anda! Khususnya x positif dan y menyiratkan kuadran pertama, y ​​positif dan x negatif, yang kedua dan seterusnya. atanatau atan2diri mereka sendiri mengembalikan angka positif atau negatif, tidak lebih.


4
Jika semua yang Anda miliki adalah p=y/xAnda masih dapat menggunakan atan2(p,1).
Mark Ransom

0

Mehrwolf di bawah ini benar, tetapi di sini ada heuristik yang dapat membantu:

Jika Anda bekerja dalam sistem koordinat 2 dimensi, yang sering terjadi untuk pemrograman invers singgung, Anda harus menggunakan pasti menggunakan atan2. Ini akan memberikan rentang pi 2 penuh sudut dan mengurus nol di koordinat x untuk Anda.

Cara lain untuk mengatakan ini adalah bahwa atan (y / x) hampir selalu salah. Hanya gunakan atan jika argumen tidak dapat dianggap sebagai y / x.


0

atan2(y,x)umumnya digunakan jika Anda ingin mengubah koordinat kartesius ke koordinat kutub. Ini akan memberi Anda sudut, sementara sqrt(x*x+y*y)atau, jika tersedia,hypot(y,x) akan memberi Anda ukuran.

atan(x)hanyalah kebalikan dari tan. Dalam kasus yang mengganggu yang harus Anda gunakan atan(y/x)karena sistem Anda tidak menyediakan atan2, Anda harus melakukan pemeriksaan tambahan untuk tanda-tanda xdan y, dan untuk x=0, untuk mendapatkan sudut yang benar.

Catatan: atan2(y,x) didefinisikan untuk semua nilai riil ydan x, kecuali untuk kasus ketika kedua argumen adalah nol.


0

Dalam atan2, output adalah: -pi< atan2(y,x)< pi
dan di atan, output adalah: -pi/2< atan(y/x)< pi/2 // itu dosis tidak mempertimbangkan kuartal.
Jika Anda ingin mendapatkan orientasi antara 0dan 2*pi(seperti matematika sekolah menengah), kita perlu menggunakan atan2 dan untuk nilai negatif tambahkan 2*piuntuk mendapatkan hasil akhir antara 0dan 2*pi.
Berikut adalah kode sumber Java untuk menjelaskannya dengan jelas:

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.