Tworzę grę kosmiczną 2d i muszę sprawić, by statek kosmiczny przechwycił planetę. Mam działający kod do przechwytywania linii prostych, ale nie mogę dowiedzieć się, jak obliczyć położenie planet na orbicie kołowej.
Gra nie jest naukowo dokładna, więc nie martwię się o bezwładność, grawitację, orbitę eliptyczną itp.
Znam lokalizację i prędkość statku kosmicznego, a także orbitę planet (promień) i prędkość
2d
mathematics
physics
Ausa
źródło
źródło
Odpowiedzi:
Analityczne rozwiązanie tego problemu jest trudne, ale możemy użyć wyszukiwania binarnego, aby znaleźć rozwiązanie z wymaganą dokładnością.
Statek może dotrzeć do najbliższego punktu na orbicie w czasie t_min :
Statek może osiągnąć DOWOLNY punkt na orbicie w czasie krótszym lub równym t_max :
(Tutaj, dla uproszczenia, zakładam, że statek może przejechać przez Słońce. Jeśli chcesz tego uniknąć, musisz przełączyć się na ścieżki nieproste przynajmniej w niektórych przypadkach. „Całowanie kół” może wyglądać ładnie i orbitalnie mechanika-y, bez zmiany algorytmu o więcej niż stały współczynnik)
Jeśli nasz okres na orbicie jest krótki, możemy być w stanie poprawić tę górną granicę, wybierając
t_max
pierwszy raz pot_min
tym, jak planeta zbliży się do pozycji początkowej statku. Weź jedną z tych dwóch wartości, którat_max
jest mniejsza. Zobacz późniejszą odpowiedź, aby dowiedzieć się, dlaczego to działa.Teraz możemy korzystać z wyszukiwania binarnego między tymi skrajnościami, t_min i t_max . Poszukamy wartości t, która zbliża błąd do zera:
(Korzystając z tej konstrukcji, błąd @ t_min> = 0 i błąd @ t_max <= 0, więc musi istnieć co najmniej jeden punkt przecięcia z błędem = 0 dla wartości t pomiędzy nimi)
gdzie, dla kompletności, funkcja pozycji jest jak ...
Zauważ, że jeśli okres obiegu orbity planety jest bardzo krótki w porównaniu z prędkością statku, ta funkcja błędu może kilkakrotnie zmieniać znaki w czasie od t_min do t_max. Śledź najwcześniejszą napotkaną parę + ve & -ve i kontynuuj wyszukiwanie między nimi, aż błąd będzie wystarczająco bliski zeru („wystarczająco blisko” wrażliwy na twoje jednostki i kontekst gry). Kwadrat połowy czasu trwania klatki może działa dobrze - zapewnia to, że przechwytywanie jest dokładne w ramce)
Kiedy już uzyskasz ładny minimalizujący błędy t, możesz po prostu skierować statek na planet.positionAtTime (t) i przejść na pełną przepustnicę, mając pewność, że planeta dotrze do tego punktu w tym samym czasie, co ty.
Zawsze możesz znaleźć rozwiązanie w iteracjach Log_2 ((2 * orbitRadius / ship.maxSpeed) / errorThreshold). Na przykład, jeśli mój statek może przemieścić orbitę w 60 klatkach, a chcę, aby przechwycenie było dokładne z dokładnością do jednej klatki, potrzebuję około 6 iteracji.
źródło
Nie komplikujmy tego zbytnio. Nie jest to „idealne” rozwiązanie, ale powinno działać w przypadku większości gier, a wszelkie niedoskonałości powinny być niewidoczne dla gracza.
Działa to, ponieważ im bliżej statek kosmiczny się zbliża, tym niższy staje się błąd. Dzięki temu obliczenia stają się bardziej stabilne w czasie.
Błąd jest różnicą między obliczonym potrzebnym czasem na dotarcie do planety (TimeNeeded) a rzeczywistym czasem potrzebnym na dotarcie do planety (po uwzględnieniu nowego TargetPoint).
źródło
Zacznijmy od przyjrzenia się matematyce stojącej za tym problemem.
Krok 1:
Znalezienie przecięcia linii z kształtem polega jedynie na wstawieniu równania linii do równania kształtu, którym w tym przypadku jest okrąg.
Weź okrąg o środku c i promieniu r . Punkt p znajduje się na okręgu, jeśli
Kwadratowa odległość może być przepisana jako iloczyn kropkowy ( http://en.wikipedia.org/wiki/Dot_product ).
Wykonaj produkt kropkowy, a my dostaniemyμ2)( v ∙ v ) - 2 μ ( a ∙ v ) + a ∙ a = r2)
Zakładać, że| v | =1 i mamy
który jest prostym równaniem kwadratowym, i dochodzimy do rozwiązania
Ifμ<0 , the line of the ship in your case does not intersect with the planets orbit.
Ifμ=0 , the line of the ship will simply touch the circle in one point.
Otherwise, this gives us twoμ -values that corresponds to two points on the orbit!
Step 2:
So we can define a line for the ship, and out of that we get either 0, 1 or 2μ -values. If we get 1 value, use that one. If we get 2, simply choose one of them.
What can we do with this? Well, we now know the distance the ship has to travel and what point it will end up in!
Now, all that is left to do is to calculate where the planet should be when the ship begins coming towards it's orbit. This is easily calculated with so called Polar coodinates (http://mathworld.wolfram.com/PolarCoordinates.html)
And since you had the speed of you ship, and we have the time it will take for the ship to reach the orbit, and where it will collide, we simply move the planet backt∗angularVelocity degrees in it's orbit, and we are done!
Summary
Choose a line for your ship, and run the math to see if it collides with the planets orbit. If it does, calculate the time it will take to get to that point. Use this time to go back in orbit from this point with the planet to calculate where the planet should be when the ship starts moving.
źródło
Here are two slightly "out of the box" solutions.
The question is: given that the ship moves in a straight line at a given velocity, and the planet moves in a circle of given radius at a given angular velocity, and the starting positions of the planet and ship, determine what direction vector the ship's straight line should be in to plot an intercept course.
Solution one: Deny the premise of the question. The quantity that is "slippable" in the question is the angle. Instead, fix that. Point the ship straight at the center of the orbit.
Solution two: Don't do it on autopilot at all. Make a mini-game where the player has to use thrusters to approach the planet, and if they hit it at too high a relative speed, they blow up, but they have limited fuel as well. Make the player learn how to solve the intercept problem!
źródło
If you dont' want to use polar coordinates, consider that the all the possible positions of the ship form a cone in(x,y,t) space. The equation for this is
wherev is the the ship velocity. It is assumed the ship starts at zero.
The position of the planet in space and time can be parametrized by e.g.
whereu goes from 0 upwards. w is the angular speed and a is the starting angle of the planet at time zero. Then solve where the ship and planet could meet in time and space. You get an equation for u to solve:
This equation needs to be solved numerically. It may have many solutions. By eyeballing it, it seems it always has a solution
źródło
Here's part of a solution. I didn't get to finish it in time. I'll try again later.
If I understand correctly, you have a planet's position & velocity, as well as a ship's position and speed. You want to get the ship's movement direction. I'm assuming the ship's and planet's speeds are constant. I also assume, without loss of generality, that the ship is at (0,0); to do this, subtract the ship's position from the planet's, and add the ship's position back onto the result of the operation described below.
Unfortunately, without latex, I can't format this answer very well, but we'll attempt to make do. Let:
s_s
= the ship's speed (s_s.x, s_s.y, likewise)s_a
= the ship's bearing (angle of movement, what we want to calculate)p_p
= the planet's initial position, global coordsp_r
= the planet's distance (radius) from the center of orbit, derivable fromp_p
p_a
= the planet's initial angle in radians, relative to the center of orbitp_s
= the planet's angular velocity (rad/sec)t
= the time to collision (this turns out to be something we must calculate as well)Here's the equations for the position of the two bodies, broken down into components:
Since we want
ship.x = planet.x
andship.y = planet.y
at some instantt
, we obtain this equation (they
case is nearly symmetrical):Solving the top equation for s_a:
Substituting this into the second equation results in a fairly terrifying equation that Wolfram alpha won't solve for me. There may be a better way to do this not involving polar coordinates. If anyone wants to give this method a shot, you're welcome to it; I've made this a wiki. Otherwise, you may want to take this to the Math StackExchange.
źródło
I would fix the location at which to intercept (graze the circle, at the "outgoing" side of the orbit.)
Now you just have to adjust the spaceship's speed so that planet and ship reach that point at the same time.
Note that the rendez-vous could be after N more orbits, depending how far away the ship is, and how fast the planet is orbiting the star.
Pick the N that in time, comes nearest to the ship's journey duration at current speed.
Then speed up or slow down ship to match the timestamp for those N orbits exactly.
In all this, the actual course is already known! Just not the speed.
źródło