Saya tahu ini adalah pertanyaan lama, tapi saya pikir ada sesuatu yang terlewatkan dalam jawaban yang diberikan sejauh ini. Dalam pertanyaan awal, rudal (atau apa pun) diperintahkan untuk mempercepat menuju posisi target. Beberapa jawaban menunjukkan bahwa ini salah, dan Anda harus mempercepat menuju tempat yang Anda pikir akan menjadi sasaran di kemudian hari. Ini lebih baik tetapi masih salah.
Apa yang benar-benar ingin Anda lakukan adalah tidak mempercepat menuju target tetapi bergerak menuju target. Cara untuk berpikir tentang ini adalah dengan mengatur kecepatan yang Anda inginkan menunjuk ke target (atau proyeksi lokasi target) dan kemudian mencari tahu akselerasi apa yang paling baik Anda terapkan (mengingat batasan apa pun yang Anda miliki, mis. Rudal mungkin tidak dapat dipercepat). secara langsung terbalik) untuk mencapai kecepatan yang Anda inginkan (mengingat bahwa kecepatan adalah vektor).
Ini adalah contoh yang berhasil saya terapkan pagi ini, dalam kasus saya untuk pemain AI dalam permainan simulasi olahraga, di mana pemain mencoba mengejar lawan mereka. Gerakan ini diatur oleh model 'tendangan-melayang' standar di mana akselerasi diterapkan pada awal timestep untuk memperbarui kecepatan dan kemudian objek melayang pada kecepatan itu selama durasi stempel waktu.
Saya akan memposting turunan ini, tetapi saya menemukan tidak ada markup matematika yang didukung di situs ini. Boo! Anda hanya perlu percaya bahwa ini adalah solusi optimal, mengingat saya bahwa saya tidak memiliki batasan pada arah percepatan, yang tidak berlaku untuk objek jenis rudal, sehingga akan memerlukan beberapa kendala tambahan.
Kode dalam python, tetapi harus dapat dibaca dengan latar belakang bahasa apa pun. Untuk kesederhanaan, saya menganggap setiap langkah waktu memiliki panjang 1 dan menyatakan kecepatan dan percepatan dalam unit yang sesuai untuk mencerminkan itu.
self.x = # current x co-ordinate
self.y = # current y co-ordinate
self.angle = # current angle of motion
self.current_speed = # current magnitude of the velocity
self.acc # Maximum acceleration player can exert on themselves
target_x = # x co-ordinate of target position or projection of it
target_y = # y co-ordinate of target position or projection of it
vx = self.current_speed * math.cos(self.angle) # current velocity x component
vy = self.current_speed * math.sin(self.angle) # current velocity y component
# Find best direction to accelerate
acc_angle = math.atan2(self.x + vx - target_x,self.y + vy - target_y)
Perhatikan bahwa fungsi atan2 (a, b) menghitung tan kebalikan dari a / b, tetapi memastikan sudut-sudutnya berada di kuadran yang benar dari sebuah lingkaran, yang mengharuskan Anda mengetahui tanda a dan b.
Dalam kasus saya, begitu saya memiliki akselerasi, saya menerapkannya untuk memperbarui kecepatannya
vx_new = vx + self.acc * math.cos(acc_angle)
vy_new = vy + self.acc * math.sin(acc_angle)
self.current_speed = math.sqrt( vx_new**2 + vy_new**2)
self.angle = math.atan2(vy_new,vx_new)
Saya juga memeriksa kecepatan baru terhadap kecepatan maks tergantung pemain dan tutup pada saat itu. Dalam hal rudal, mobil atau sesuatu dengan kecepatan belok maksimum (dalam derajat per tick) Anda cukup melihat sudut gerakan saat ini versus ideal yang dihitung dan jika perubahan ini lebih besar dari yang diperbolehkan, ubah saja sudutnya dengan sebisa mungkin menuju yang ideal.
Bagi siapa pun yang tertarik dengan derivasi ini, saya menuliskan jarak antara pemain dan target setelah timstep, dalam hal posisi awal, kecepatan, laju akselerasi dan sudut akselerasi, kemudian mengambil turunan dengan memperhatikan sudut akselerasi. Menetapkan bahwa ke nol menemukan minimum dari jarak target pemain setelah timestep sebagai fungsi dari sudut akselerasi, yang persis apa yang ingin kita ketahui. Menariknya, meskipun tingkat akselerasi awalnya dalam persamaan, itu membatalkan membuat arah yang optimal terlepas dari seberapa banyak Anda benar-benar dapat mempercepat.