Estou criando um jogo espacial 2D e preciso fazer a nave interceptar um planeta. Eu tenho código de trabalho para interceptações em linha reta, mas não consigo descobrir como calcular a localização dos planetas em uma órbita circular.
O jogo não é cientificamente preciso, então não estou preocupado com inércia, gravidade, órbitas elípticas, etc.
Eu sei a localização e velocidade das naves espaciais e também os planetas orbitam (Radius) e a velocidade
2d
mathematics
physics
Ausa
fonte
fonte
Respostas:
Uma solução analítica para isso é difícil, mas podemos usar a pesquisa binária para encontrar uma solução com a precisão necessária.
A nave pode chegar ao ponto mais próximo da órbita no tempo t_min :
A nave pode atingir QUALQUER ponto da órbita em tempo menor ou igual a t_max :
(Aqui, por simplicidade, presumo que o navio possa dirigir pelo sol. Se você quiser evitar isso, precisará mudar para caminhos não lineares por pelo menos alguns casos. "Beijar círculos" pode parecer agradável e orbital mecânica-y, sem alterar o algoritmo por mais que um fator constante)
Se nosso período orbital for curto, poderemos melhorar esse limite superior, escolhendo
t_max
a primeira vez depoist_min
que o planeta se aproximar mais da posição inicial da nave. Tome qualquer um desses dois valorest_max
menor. Veja esta resposta posterior para obter uma derivação de por que isso funciona.Agora podemos usar a pesquisa binária entre esses extremos, t_min e t_max . Procuraremos um valor t que obtenha o erro próximo de zero:
(Usando essa construção, erro @ t_min> = 0 e erro @ t_max <= 0, portanto, deve haver pelo menos uma interceptação com erro = 0 para um valor t intermediário)
onde, para completar, a função position é algo como ...
Observe que, se o período orbital do planeta for muito curto comparado à velocidade da nave, esta função de erro poderá alterar os sinais várias vezes ao longo do intervalo de t_min a t_max. Apenas acompanhe o par mais antigo de ve e -v que você encontrar e continue pesquisando entre eles até que o erro esteja próximo o suficiente de zero ("perto o suficiente" sendo sensível às suas unidades e ao contexto de jogo. O quadrado da metade da duração do quadro pode funciona bem - que garante que a interceptação seja precisa dentro de um quadro)
Depois de ter um bom t minimizador de erros, basta apontar a nave para planet.positionAtTime (t) e acelerar a toda velocidade, confiante de que o planeta alcançará esse ponto ao mesmo tempo que você.
Você sempre pode encontrar uma solução nas iterações Log_2 ((2 * orbitRadius / ship.maxSpeed) / errorThreshold). Por exemplo, se minha nave puder atravessar a órbita em 60 quadros e eu desejar uma interceptação precisa dentro de um quadro, precisarei de cerca de 6 iterações.
fonte
Não vamos complicar demais isso. Esta não é uma solução "perfeita", mas deve funcionar para a maioria dos jogos e qualquer imperfeição deve ser invisível para o jogador.
Isso funciona porque quanto mais próxima a espaçonave fica, mais baixo se torna o erro. Portanto, o cálculo se torna mais estável ao longo do tempo.
O erro é a diferença entre o tempo calculado necessário para alcançar o planeta (TimeNeeded) e o tempo real necessário para alcançar o planeta (depois de levar em consideração o novo TargetPoint).
fonte
Vamos começar dando uma olhada na matemática por trás do problema.
Passo 1:
Encontrar a interseção entre uma linha e uma forma é apenas uma questão de inserir a equação da linha na equação da forma, que neste caso é um círculo.
Faça um círculo com o centro ce raio r . Um ponto p está no círculo se
Com uma linha expressa comop=p0+μv (onde v é um vetor, http://en.wikipedia.org/wiki/Euclidean_vector ), você insere a linha na fórmula do círculo e obtém
A distância ao quadrado pode ser reescrita como um produto escalar ( http://en.wikipedia.org/wiki/Dot_product ).
que é uma equação quadrática simples, e chegamos à solução
Passo 2:
O que podemos fazer com isso? Bem, agora sabemos a distância que o navio deve percorrer e em que ponto ele terminará!
Agora, tudo o que resta fazer é calcular onde o planeta deve estar quando a nave começar a se aproximar de sua órbita. Isso é facilmente calculado com os chamados coodinatos polares ( http://mathworld.wolfram.com/PolarCoordinates.html )
Sumário
Escolha uma linha para sua nave e faça a matemática para ver se ela colide com a órbita dos planetas. Nesse caso, calcule o tempo necessário para chegar a esse ponto. Use esse tempo para voltar em órbita a partir deste ponto com o planeta para calcular onde o planeta deve estar quando a nave começar a se mover.
fonte
Aqui estão duas soluções "prontas para uso".
A questão é: dado que a nave se move em uma linha reta a uma velocidade determinada, e o planeta se move em um círculo de raio determinado a uma velocidade angular determinada, e as posições iniciais do planeta e da nave, determinam qual direção o vetor da nave deve haver uma linha reta para traçar um percurso de interceptação
Solução 1: Negue a premissa da pergunta. A quantidade "deslizável" na pergunta é o ângulo. Em vez disso, conserte isso. Aponte o navio diretamente para o centro da órbita.
Solução 2: Não faça isso no piloto automático. Faça um mini-jogo no qual o jogador precise usar propulsores para se aproximar do planeta e, se o atingirem em uma velocidade relativa muito alta, eles explodem, mas também têm combustível limitado. Faça o jogador aprender a resolver o problema de interceptação!
fonte
A posição do planeta no espaço e no tempo pode ser parametrizada por
Ondevocê vai de 0 0 para cima. W é a velocidade angular e uma 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
fonte
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.
fonte
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.
fonte