Sé que esta es una pregunta antigua, pero creo que hay algo que se ha perdido en las respuestas dadas hasta ahora. En la pregunta original, se le dijo al misil (o lo que sea) que acelerara hacia la posición del objetivo. Varias respuestas señalaron que esto estaba mal, y debe acelerar hacia donde cree que estará el objetivo en algún momento posterior. Esto es mejor pero aún está mal.
Lo que realmente quieres hacer no es acelerar hacia el objetivo, sino avanzar hacia el objetivo. La forma de pensar en esto es establecer su velocidad deseada apuntando al objetivo (o una proyección de la ubicación de los objetivos) y luego determinar qué aceleración podría aplicar mejor (dadas las restricciones que tenga, es decir, un misil probablemente no puede acelerar directamente en reversa) para alcanzar la velocidad deseada (recordando que la velocidad es un vector).
Aquí hay un ejemplo trabajado que implementé esta mañana, en mi caso para un jugador AI en un juego de simulación deportiva, donde el jugador está tratando de perseguir a su oponente. El movimiento se rige por un modelo estándar de "patada de deriva" donde las aceleraciones se aplican al comienzo de un paso de tiempo para actualizar las velocidades y luego los objetos se desplazan a esa velocidad durante la duración del paso de tiempo.
Publicaría la derivación de esto, pero he descubierto que no hay soporte de marcado matemático en este sitio. ¡Abucheo! Solo tendrá que confiar en que esta es la solución óptima, teniendo en cuenta que no tengo restricciones en la dirección de aceleración, que no es el caso de un objeto de tipo misil, por lo que eso requeriría algunas restricciones adicionales.
El código está en Python, pero debe ser legible con cualquier fondo de idioma. Para simplificar, supongo que cada paso de tiempo tiene una longitud de 1 y expreso la velocidad y la aceleración en unidades apropiadas para reflejar eso.
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)
Tenga en cuenta que la función atan2 (a, b) calcula el tan inverso de a / b, pero asegura que los ángulos se asienten en el cuadrante correcto de un círculo, lo que requiere conocer el signo de a y b.
En mi caso, una vez que tengo la aceleración, la aplico para actualizar la velocidad
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)
También compruebo la nueva velocidad contra la velocidad máxima dependiente de un jugador y la limito. En el caso de un misil, automóvil o algo con una velocidad de giro máxima (en grados por tic), simplemente puede mirar el ángulo de movimiento actual versus el ideal calculado y si este cambio es mayor de lo permitido, simplemente cambie el ángulo como tanto como sea posible hacia el ideal.
Para cualquier persona interesada en la derivación de esto, escribí la distancia entre el jugador y el objetivo después del paso, en términos de posición inicial, velocidad, tasa de aceleración y ángulo de aceleración, luego tomé la derivada con respecto al ángulo de aceleración. Al establecer eso en cero, se encuentran los mínimos de la distancia objetivo-jugador después del paso de tiempo en función del ángulo de aceleración, que es exactamente lo que queremos saber. Curiosamente, a pesar de que la tasa de aceleración estaba originalmente en las ecuaciones, se cancela haciendo que la dirección óptima sea independiente de cuánto puede acelerar realmente.