Jawaban:
std::atan2
memungkinkan menghitung arctangent dari keempat kuadran. std::atan
hanya memungkinkan penghitungan dari kuadran 1 dan 4.
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
, cos
dan tan
memiliki 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 y
dan x
argumen, yang merupakan proyeksi dari vektor dengan panjang v
dan 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.
Satu hal lagi yang atan2
lebih stabil ketika menghitung garis singgung menggunakan ekspresi like atan(y / x)
dan x
0 atau mendekati 0.
Nilai aktual dalam radian tetapi untuk menafsirkannya dalam derajat itu akan:
atan
= memberikan nilai sudut antara -90 dan 90atan2
= memberikan nilai sudut antara -180 dan 180Untuk pekerjaan saya yang melibatkan perhitungan berbagai sudut seperti pos dan bantalan navigasi, atan2
dalam banyak kasus melakukan pekerjaan.
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.
(-pi,pi]
tetapi atan2 memiliki rentang [-pi,pi]
sehingga mencakup satu nilai tambahan -pi
dari cabang lain karena atan2(-0.0,x)
untuk x<0
.
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.
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.
atan
digunakan 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 atan2
untuk menentukan kuadran, Anda dapat menggunakan atan2
hanya 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. atan
atau atan2
diri mereka sendiri mengembalikan angka positif atau negatif, tidak lebih.
p=y/x
Anda masih dapat menggunakan atan2(p,1)
.
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.
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 x
dan y
, dan untuk x=0
, untuk mendapatkan sudut yang benar.
Catatan: atan2(y,x)
didefinisikan untuk semua nilai riil y
dan x
, kecuali untuk kasus ketika kedua argumen adalah nol.
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 0
dan 2*pi
(seperti matematika sekolah menengah), kita perlu menggunakan atan2 dan untuk nilai negatif tambahkan 2*pi
untuk mendapatkan hasil akhir antara 0
dan 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
-π/2 <= atan() <= π/2
sebenarnya mencakup satu titik (pi/2
) dari kuadran II.