Dalam game 2D, saya hanya ingin menggambar lintasan panah dalam penerbangan. Dengan kode di bawah ini, lintasan (parabola) terlihat benar, tetapi sudut (atau rotasi) atau panahnya tidak.
float g = -9.8f;
float x = (launchVelocity * time);
float y = (launchVelocity * time) + (0.5f * g * (float)Math.Pow(time, 2));
float angle = (float)Math.Tanh(y / x);
Apa yang saya lewatkan? Terima kasih.
projectile-physics
Martin
sumber
sumber
Jawaban:
Arctanh
memberi Anda garis singgung untuk kurva hiperbolik! Sejauh yang saya tahu parabola Anda bukan hiperbola.Tapi kami punya kabar baik: menemukan garis singgung untuk parabola Anda lebih mudah. Persamaannya adalah
Di mana milikmu
launchVelocity
. Sekarang kemiringan panah Anda adalah:Anda dapat menggunakan keamanan
Arctan
sekarang jika Anda mau.Beberapa info tambahan tentang fisika:
Perkiraan lintasan yang Anda simulasikan berlaku untuk pusat massa panah Anda. Ketika Anda mengatakan "posisi" (x, y) Anda berbicara tentang posisi pusat massa. Pusat massa untuk panah sedikit maju dari titik tengah dan Anda harus memperhitungkannya jika Anda akan menggambar panah.
Ingatlah bahwa Anda tidak mempertimbangkan momentum inersia panah (yang dapat sangat bervariasi jika Anda menembakkan ballista raksasa) dan Anda tidak mempertimbangkan dinamika fluida panah: penerbangan panah tidak akan mengikuti jalur parabola!
sumber
Anda ingin sudut panah pada suatu titik waktu. Anda ingat bahwa untuk menghitung sudut, ada garis singgung. Tapi di sinilah pemikiran Anda mulai salah:
Ok, jadi jika Anda mengabaikan gesekan udara, maka kecepatan x panah adalah konstan.
Pertama, dekomposisi kecepatan menjadi komponen x dan y. Anda bisa memotret pada sudut 45 derajat atau 60 derajat. Jadi, Anda perlu launchVelocity dan sudut, itu bukan skalar.
Kedua, hitung semuanya sebagai ganda, bukan mengambang. Secara numerik Anda tidak cukup canggih untuk mengetahui kapan kesalahan pembulatan tidak akan membunuh Anda, jadi jangan coba-coba. Bagaimanapun, ini bukan penghemat waktu yang tepat.
Ketiga, jangan gunakan Math.pow, lambat dan tidak seakurat mengalikan untuk kekuatan integer. Anda juga dapat menghemat banyak waktu dengan menggunakan formulir Horner (lihat di bawah)
Jika Anda sangat membutuhkan kinerja, Anda bahkan dapat melakukan precompute 0,5 * g, tetapi kode di atas akan membawa Anda 90% dari perjalanan ke sana tanpa melakukan sesuatu yang terlalu gila. Benchmark melakukan ini 10 juta kali jika Anda mau, ini memang diakui bukan jumlah yang besar, tetapi secara persentase itu cukup besar - perpustakaan sangat lambat di Jawa
Jadi, jika Anda ingin sudut di mana panah harus pergi, yang Anda inginkan adalah
Dan dalam hal ini, itu akan berhasil karena dx adalah konstanta. Tetapi secara umum, dx bisa menjadi nol, jadi Anda biasanya ingin menggunakan:
yang merupakan fungsi yang dirancang khusus untuk pekerjaan ini.
Tapi seperti yang saya katakan, fungsi perpustakaan di Jawa sangat lambat, dan dalam hal ini ada cara yang lebih baik untuk melakukannya tanpa disinggung oleh @FxIII di atas.
Jika kecepatan horizontal selalu v0x, dan kecepatan vertikal adalah:
maka delta Anda adalah: vx, vy
Anda tidak perlu sudut. Jika Anda ingin menggambar panah, gunakan sesuatu yang nominal seperti:
plot (x, y, x + vx, y + vy);
Saya tidak tahu apa yang Anda gambar, jadi jika Anda perlu sudut untuk memutarnya (seperti Anda menggunakan JOGL) maka tentu saja, gunakan sudutnya.
Jangan lupa jika Anda menggunakan opengl untuk mengubah sudut kembali menjadi derajat, karena ATAN2 mengembalikan radian:
sumber
Tanh () ( garis singgung hiperbolik ) mengambil sudut sebagai parameter, tetapi Anda telah memberinya rasio sisi.
Yang Anda inginkan adalah menggunakan arctangent hiperbolik , yang menggunakan rasio sisi sebagai parameter, dan mengembalikan sudutnya. (Penamaan ini mungkin "atanh", "atanh2", "arctanh", atau sesuatu yang serupa; tampaknya sangat bervariasi antara perpustakaan matematika yang berbeda)
sumber