Solusi analitik untuk ini sulit, tetapi kita dapat menggunakan pencarian biner untuk menemukan solusi dalam akurasi yang diperlukan.
Kapal dapat mencapai titik terdekat di orbit dalam waktu t_min :
shipOrbitRadius = (ship.position - planet.orbitCenter).length;
shortestDistance = abs(shipOrbitRadius - planet.orbitRadius);
t_min = shortestDistance/ship.maxSpeed;
Kapal dapat mencapai titik APAPUN di orbit dalam waktu kurang dari atau sama dengan t_max :
(Di sini, untuk kesederhanaan, saya menganggap kapal dapat mengemudi melalui matahari. Jika Anda ingin menghindari ini, Anda perlu beralih ke jalur non-garis lurus untuk setidaknya beberapa kasus. "Lingkaran ciuman" mungkin terlihat bagus dan orbital mekanika-y, tanpa mengubah algoritme lebih dari faktor konstan)
if(shipOrbitRadius > planet.orbitRadius)
{
t_max = planet.orbitRadius * 2/ship.maxSpeed + t_min;
}
else
{
t_max = planet.orbitRadius * 2/ship.maxSpeed - t_min;
}
Jika periode orbit kita pendek, kita mungkin dapat meningkatkan batas atas ini dengan memilih t_max
untuk menjadi yang pertama kalinya setelah t_min
itu, planet ini melakukan pendekatan terdekat dengan posisi awal kapal. Ambil yang mana dari kedua nilai t_max
ini yang lebih kecil. Lihat jawaban ini nanti untuk penjelasan mengapa ini bekerja.
Sekarang kita dapat menggunakan pencarian biner antara ekstrem ini, t_min dan t_max . Kami akan mencari nilai-t yang membuat kesalahan mendekati nol:
error = (planet.positionAtTime(t) - ship.position).squareMagnitude/(ship.maxSpeed*ship.maxSpeed) - t*t;
(Menggunakan konstruksi ini, error @ t_min> = 0 dan error @ t_max <= 0, jadi harus ada setidaknya satu intersep dengan error = 0 untuk nilai-t di antaranya)
di mana, untuk kelengkapan, fungsi posisi adalah seperti ...
Vector2 Planet.positionAtTime(float t)
{
angle = atan2(startPosition - orbitCenter) + t * orbitalSpeedInRadians;
return new Vector2(cos(angle), sin(angle)) * orbitRadius + orbitCenter;
}
Perhatikan bahwa jika periode orbit planet ini sangat singkat dibandingkan dengan kecepatan kapal, fungsi kesalahan ini dapat mengubah tanda beberapa kali selama rentang waktu dari t_min ke t_max. Pantau terus pasangan + ve & -ve yang paling awal yang Anda temui, dan lanjutkan mencari di antara mereka sampai kesalahannya cukup dekat ke nol ("cukup dekat" peka terhadap unit dan konteks gameplay Anda. Kuadrat dari setengah durasi bingkai mungkin bekerja dengan baik - yang memastikan intersepsi akurat dalam bingkai)
Setelah Anda memiliki t meminimalkan meminimalkan kesalahan yang baik, Anda bisa mengarahkan kapal di planet.positionAtTime (t) dan pergi kecepatan penuh, yakin bahwa planet akan mencapai titik itu pada saat yang sama Anda lakukan.
Anda selalu dapat menemukan solusi dalam iterasi Log_2 ((2 * orbitRadius / ship.maxSpeed) / errorThreshold). Jadi misalnya, jika kapal saya dapat melintasi orbit dalam 60 frame, dan saya ingin intersep akurat dalam satu frame, saya akan membutuhkan sekitar 6 iterasi.