Sei que essa é uma pergunta antiga, mas acho que há algo que foi esquecido nas respostas dadas até agora. Na pergunta original, o míssil (ou o que fosse) foi instruído a acelerar em direção à posição do alvo. Várias respostas apontaram que isso estava errado, e você deve acelerar para onde acha que o alvo estará em algum momento posterior. Isso é melhor, mas ainda está errado.
O que você realmente deseja fazer não é acelerar em direção ao alvo, mas avançar em direção ao alvo. A maneira de pensar sobre isso é definir a velocidade desejada apontada para o alvo (ou uma projeção da localização dos alvos) e, em seguida, descobrir qual aceleração você poderia aplicar melhor (dadas as restrições que tiver, por exemplo, um míssil provavelmente não pode ser acelerado). diretamente no sentido inverso) para atingir a velocidade desejada (lembrando que a velocidade é um vetor).
Aqui está um exemplo que eu implementei esta manhã, no meu caso de uma IA de jogador em um jogo de simulação de esportes, onde o jogador está tentando perseguir seu oponente. O movimento é governado por um modelo padrão de 'kick-drift', no qual as acelerações são aplicadas no início de um timestep para atualizar as velocidades e, em seguida, os objetos derivam nessa velocidade durante o timestap.
Eu publicaria a derivação disso, mas descobri que não há marcação matemática suportada neste site. Vaia! Você apenas terá que confiar que esta é a solução ideal, considerando que eu não tenho restrições na direção da aceleração, o que não é o caso de um objeto do tipo míssil, de modo que exigiria algumas restrições extras.
O código está em python, mas deve ser legível em qualquer fundo da linguagem. Por uma questão de simplicidade, presumo que cada etapa do tempo tem um comprimento de 1 e expresso a velocidade e a aceleração em unidades apropriadas para refletir isso.
self.x = # current x co-ordinate
self.y = # current y co-ordinate
self.angle = # current angle of motion
self.current_speed = # current magnitude of the velocity
self.acc # Maximum acceleration player can exert on themselves
target_x = # x co-ordinate of target position or projection of it
target_y = # y co-ordinate of target position or projection of it
vx = self.current_speed * math.cos(self.angle) # current velocity x component
vy = self.current_speed * math.sin(self.angle) # current velocity y component
# Find best direction to accelerate
acc_angle = math.atan2(self.x + vx - target_x,self.y + vy - target_y)
Observe que a função atan2 (a, b) calcula o tan inverso de a / b, mas garante que os ângulos fiquem no quadrante correto de um círculo, o que requer conhecer o sinal de a e b.
No meu caso, uma vez que tenho a aceleração, aplico isso para atualizar a velocidade
vx_new = vx + self.acc * math.cos(acc_angle)
vy_new = vy + self.acc * math.sin(acc_angle)
self.current_speed = math.sqrt( vx_new**2 + vy_new**2)
self.angle = math.atan2(vy_new,vx_new)
Eu também verifico a nova velocidade em relação à velocidade máxima dependente de um jogador e a limito a isso. No caso de um míssil, carro ou algo com uma taxa de giro máxima (em graus por tick), você pode simplesmente olhar o ângulo de movimento atual versus o ideal calculado e, se essa alteração for maior do que o permitido, basta alterar o ângulo da seguinte maneira: tanto quanto possível em direção ao ideal.
Para qualquer pessoa interessada na derivação disso, anotei a distância entre o jogador e o alvo após o passo do tempo, em termos de posição inicial, velocidade, taxa de aceleração e ângulo de aceleração, e depois tomei a derivada em relação ao ângulo de aceleração. Definir esse valor como zero encontra os mínimos da distância entre o jogador e o alvo após o timestep em função do ângulo de aceleração, que é exatamente o que queremos saber. Curiosamente, embora a taxa de aceleração estivesse originalmente nas equações, ela cancela, tornando a direção ideal independente de quanto você é capaz de acelerar.