Saya akan berasumsi bahwa Anda memiliki gerakan yang benar secara fisik untuk kapal Anda, karena jika tidak analisis ini tidak akan berlaku. Anda membutuhkan sesuatu yang lebih kuat daripada efisiensi untuk menyelesaikan masalah ini dengan benar.
Setiap pendorong akan menghasilkan dua efek pada pergerakan kapal: linear dan angular. Ini dapat dipertimbangkan secara independen. Jika pendorong menghasilkan gaya f
dalam arah dir
, dan diimbangi dari pusat massa oleh vektor r
(bukan pusat geometris atau pusat sprite!), Maka efek pada komponen linier adalah:
t = f * dir // f is a scalar, dir is unit length
Efek pada kecepatan sudut diberikan oleh torsi:
tau = f * <dir.x, dir.y, 0> CROSS <r.x, r.y, 0> // cross product
t
adalah vektor gaya (yaitu dorongan linier). tau
adalah skalar yang ditandatangani, yang bila dibagi dengan momen massa inersia, akan memberikan percepatan sudut. Adalah penting bahwa dir
dan r
keduanya berada dalam ruang koordinat yang sama, yaitu dalam koordinat lokal atau keduanya dalam koordinat dunia.
Akselerasi linear keseluruhan kapal diberikan oleh jumlah t
's untuk setiap pendorong dibagi dengan massa kapal. Demikian pula, percepatan sudut hanyalah jumlah torsi yang dibagi dengan momen massa inersia (yang merupakan skalar lain). Kapal tidak akan berputar jika torsi totalnya nol. Demikian pula, itu tidak akan bergerak jika total dorong adalah nol. Ingat torsi adalah skalar tetapi dorong (jumlah dari t
) adalah vektor 2D.
Maksud dari paparan ini adalah bahwa sekarang kita dapat menulis masalah kita sebagai Program Linear . Katakan dulu kita ingin kapal kita berputar tanpa bergerak . Kami memiliki variabel untuk setiap pendorong, $ x_1, x_2, ... $, yang merupakan jumlah daya dorong yang akan diberikan pendorong. Satu set kendala adalah:
0 <= x_i < fmax_i //for each i
di mana fmax
kekuatan maksimum untuk pendorong itu (ini memungkinkan kita memiliki yang lebih kuat atau lebih lemah). Selanjutnya, kita katakan bahwa keduanya sama:
0 = Sum_i x_i * dir_i.x
0 = Sum_i x_i * dir_i.y
Ini mengkodekan batasan bahwa kita tidak akan menerapkan percepatan linear, dengan mengatakan total dorong adalah nol (dorong adalah vektor, jadi kita hanya mengatakan setiap bagian adalah nol).
Sekarang kami ingin kapal kami berputar. Mungkin kami ingin melakukannya secepat mungkin, jadi kami ingin:
max (Sum_i x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0>
Memecahkan untuk x_i
sementara memuaskan ketidaksetaraan dan kesetaraan di atas, sambil memaksimalkan penjumlahan di atas, akan memberi kita dorongan yang diinginkan. Sebagian besar bahasa pemrograman memiliki perpustakaan LP yang tersedia untuk mereka. Masukkan saja masalah di atas ke dalamnya dan itu akan menghasilkan jawaban Anda.
Masalah serupa akan membuat kita bergerak tanpa berbelok. Katakanlah kita menulis ulang masalah kita dalam sistem koordinat di mana kita ingin bergerak ke arah x positif. Maka kendalanya adalah:
0 <= x_i < fmax_i //for each i
max Sum_i x_i * dir_i.x
0 = Sum_i x_i * dir_i.y
0 = (Sum_i x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0> // as before
Dengan batasan bahwa pendorong hanya dapat menghasilkan pendorong dalam satu arah, akan ada batasan untuk jenis rotasi dan kecepatan linier yang dapat Anda capai. Ini akan bermanifestasi sebagai solusi 0 = x_1 = x_2 = ... = x_n
, yang berarti Anda tidak akan pernah ke mana pun. Untuk mengurangi ini, saya sarankan menambahkan sepasang pendorong kecil, lemah (katakanlah 5%, atau 10%) untuk setiap pemain menempatkan pendorong pada 45 derajat di kedua sisi. Ini akan memberikan solusi lebih fleksibel, karena ini dapat digunakan untuk menangkal efek sekunder pendorong utama yang lemah.
Akhirnya, hingga 100 pendorong, solusi untuk LP cukup cepat untuk dilakukan per frame. Namun, karena solusinya tidak tergantung pada lokasi atau keadaan saat ini, Anda dapat melakukan prekomputasi solusi untuk setiap kombinasi input pengontrol yang masuk akal setiap kali perubahan bentuk (ini termasuk menambahkan non-pendorong yang mengubah momen inersia atau massa kapal, karena kemudian pendorong berada di lokasi yang berbeda relatif terhadap pusat massa!). Ini adalah 24 kemungkinan (mis. 8 arah kali {putaran kiri, tidak ada putaran, putaran kanan}).