Buna analitik bir çözüm zordur, ancak istenen doğrulukta bir çözüm bulmak için ikili arama kullanabiliriz .
Gemi t_min zamanında yörüngedeki en yakın noktaya ulaşabilir :
shipOrbitRadius = (ship.position - planet.orbitCenter).length;
shortestDistance = abs(shipOrbitRadius - planet.orbitRadius);
t_min = shortestDistance/ship.maxSpeed;
Gemi yörüngedeki herhangi bir noktaya t_max değerine eşit veya daha az sürede ulaşabilir :
(Burada, basitlik için, geminin güneşten geçebileceğini varsayıyorum. Bundan kaçınmak istiyorsan, en azından bazı durumlar için düz olmayan yollara geçmen gerekecek. "Öpüşen daire" güzel ve yörüngeye benzeyebilir. mechanics-y, algoritmayı sabit bir faktörden daha fazla değiştirmeden)
if(shipOrbitRadius > planet.orbitRadius)
{
t_max = planet.orbitRadius * 2/ship.maxSpeed + t_min;
}
else
{
t_max = planet.orbitRadius * 2/ship.maxSpeed - t_min;
}
Yörünge periyodumuz kısaysa, gezegenin geminin başlangıç konumuna en yakın yaklaşmasını sağlamasının t_max
ardından ilk defa olmasını seçerek bu üst sınır üzerinde gelişebiliriz t_min
. Bu iki değerden hangisi t_max
daha küçükse onu alın. Bunun neden işe yaradığının bir türevi için bu cevaba bakınız.
Şimdi bu aşırı uçlar, t_min ve t_max arasında ikili aramayı kullanabiliriz . Hatayı sıfıra yaklaştıracak bir t değeri arayacağız :
error = (planet.positionAtTime(t) - ship.position).squareMagnitude/(ship.maxSpeed*ship.maxSpeed) - t*t;
(Bu yapı kullanılarak, hata @ t_min> = 0 ve hata @ t_max <= 0, bu nedenle aradaki bir t değeri için en az bir hata = 0 olan bir kesme olmalıdır)
tamlık için pozisyon işlevi ...
Vector2 Planet.positionAtTime(float t)
{
angle = atan2(startPosition - orbitCenter) + t * orbitalSpeedInRadians;
return new Vector2(cos(angle), sin(angle)) * orbitRadius + orbitCenter;
}
Gezegenin yörünge periyodunun geminin hızına göre çok kısa olması durumunda, bu hata fonksiyonunun aralık boyunca t_min'den t_max'a kadar işaretleri birkaç kez değiştirebileceğini unutmayın. Sadece karşılaştığınız en eski + ve -veve çiftlerini takip edin ve hata sıfıra yakın olana kadar aralarında aramaya devam edin ("yeterince yakın" ünitelerinize ve oyun bağlamınıza duyarlı olmak. Kare süresinin yarısı karesi olabilir. iyi çalışın - bu müdahalenin bir çerçeve içinde doğru olmasını sağlar)
Hatayı en aza indirgeyen bir kez, gemiyi planet.positionAtTime (t) 'ye yönlendirebilir ve tam gaz kullanıp, gezegenin aynı zamanda bu noktaya ulaşacağından emin olabilirsiniz.
Log_2 ((2 * orbitRadius / ship.maxSpeed) / errorThreshold) yinelemelerinde her zaman bir çözüm bulabilirsiniz. Örneğin, eğer gemim yörüngeyi 60 kare içinde geçebiliyorsa ve bir kare içinde doğru bir kesişme noktası istiyorsam, yaklaşık 6 yinelemeye ihtiyacım olacak.