โซลูชันการวิเคราะห์สำหรับสิ่งนี้เป็นเรื่องยาก แต่เราสามารถใช้การค้นหาแบบไบนารีเพื่อค้นหาวิธีแก้ไขภายในความแม่นยำที่จำเป็น
เรือสามารถไปถึงจุดที่ใกล้ที่สุดบนวงโคจรในเวลาt_min :
shipOrbitRadius = (ship.position - planet.orbitCenter).length;
shortestDistance = abs(shipOrbitRadius - planet.orbitRadius);
t_min = shortestDistance/ship.maxSpeed;
เรือสามารถไปถึงจุดใดก็ได้บนวงโคจรในเวลาน้อยกว่าหรือเท่ากับt_max :
(ที่นี่เพื่อความเรียบง่ายฉันคิดว่าเรือสามารถขับผ่านดวงอาทิตย์ได้ถ้าคุณต้องการหลีกเลี่ยงสิ่งนี้คุณจะต้องเปลี่ยนไปใช้เส้นทางที่ไม่ใช่เส้นตรงอย่างน้อยในบางกรณี "วงจูบ" อาจดูดีและโคจร กลไก -y โดยไม่ต้องเปลี่ยนอัลกอริทึมมากกว่าปัจจัยคงที่)
if(shipOrbitRadius > planet.orbitRadius)
{
t_max = planet.orbitRadius * 2/ship.maxSpeed + t_min;
}
else
{
t_max = planet.orbitRadius * 2/ship.maxSpeed - t_min;
}
หากระยะเวลาการโคจรของเราสั้นเราอาจสามารถปรับปรุงขอบเขตบนนี้ได้โดยเลือกที่t_max
จะเป็นครั้งแรกหลังจากt_min
นั้นดาวเคราะห์ก็เข้าใกล้จุดเริ่มต้นของเรือมากที่สุด ใช้ค่าใดของค่าสองค่าt_max
นี้ที่น้อยกว่า ดูคำตอบนี้ในภายหลังเพื่อหาสาเหตุของการทำงาน
ตอนนี้เราสามารถใช้การค้นหาแบบไบนารีระหว่างขั้วเหล่านี้t_minและt_max เราจะค้นหาค่า t ที่ทำให้เกิดข้อผิดพลาดใกล้กับศูนย์:
error = (planet.positionAtTime(t) - ship.position).squareMagnitude/(ship.maxSpeed*ship.maxSpeed) - t*t;
(การใช้โครงสร้างนี้ข้อผิดพลาด @ t_min> = 0 และข้อผิดพลาด @ t_max <= 0 ดังนั้นจะต้องมีอย่างน้อยหนึ่งจุดตัดที่มีข้อผิดพลาด = 0 สำหรับค่า t ในระหว่าง)
ฟังก์ชั่นตำแหน่งเป็นอะไรที่ ...
Vector2 Planet.positionAtTime(float t)
{
angle = atan2(startPosition - orbitCenter) + t * orbitalSpeedInRadians;
return new Vector2(cos(angle), sin(angle)) * orbitRadius + orbitCenter;
}
โปรดทราบว่าหากระยะเวลาการโคจรของดาวเคราะห์สั้นมากเมื่อเทียบกับความเร็วของเรือฟังก์ชั่นข้อผิดพลาดนี้อาจเปลี่ยนสัญญาณหลายครั้งในช่วงจาก t_min ถึง t_max ติดตามคู่ที่เร็วที่สุด & ve ได้ที่คุณพบและทำการค้นหาต่อไปเรื่อย ๆ จนกว่าข้อผิดพลาดจะใกล้ถึงศูนย์ ("ใกล้พอ" ที่ไวต่อหน่วยของคุณและบริบทการเล่นเกมตารางครึ่งระยะเวลาเฟรมอาจ ทำงานได้ดี - ช่วยให้มั่นใจว่าการสกัดกั้นนั้นแม่นยำภายในเฟรม)
เมื่อคุณมีข้อผิดพลาดในการลดความผิดพลาดได้ดีคุณสามารถชี้เรือไปที่ดาวเคราะห์ได้ตำแหน่งเวลา (t) และเร่งความเร็วเต็มที่มั่นใจว่าโลกจะไปถึงจุดนั้นในเวลาเดียวกันกับที่คุณทำ
คุณสามารถค้นหาวิธีแก้ปัญหาภายในการวนซ้ำ Log_2 ((2 * orbitRadius / ship.maxSpeed) / errorThreshold) ตัวอย่างเช่นถ้าเรือของฉันสามารถเคลื่อนที่วงโคจรใน 60 เฟรมและฉันต้องการการสกัดกั้นที่แม่นยำภายในหนึ่งเฟรมฉันจะต้องใช้การประมาณ 6 ครั้ง