Enfoques para detectar si un automobile debe girar a la izquierda o a la derecha considerando una próxima dirección

Estoy desarrollando la IA de mi juego de carreras , y estoy teniendo un problema imprevisto. Me las arreglo para que el robot pueda conducir solo al acelerar en la dirección de un ángulo que se devuelve utilizando la function de trig atan2 considerando la position de los puntos de reference previamente definidos en la estructura de datos de la pista. Aquí está el código para ai.py :

 import math import pygame class Bot: def __init__(self, player, track): self.player = player self.track = track self.current_waypoint = 1 self.player.states[0] = True self.track.choose_waypoint_path() self.number_of_waypoints = len(self.track.waypoint_positions.keys()) self.get_waypoint_angle() def get_waypoint_angle(self): self.dx = self.track.waypoint_positions[self.current_waypoint][0] - self.player.car.pos[0] self.dy = self.track.waypoint_positions[self.current_waypoint][1] - self.player.car.pos[1] self.ratio = math.atan2(self.dy, self.dx) self.angle = -self.ratio * (180/math.pi) def think(self): if pygame.Rect(self.player.car.pos, self.player.car.dimensions).collidepoint( self.track.waypoint_positions[self.current_waypoint][0], self.track.waypoint_positions[self.current_waypoint][1] ): self.track.choose_waypoint_path() self.number_of_waypoints = len(self.track.waypoint_positions.keys()) if self.current_waypoint == self.number_of_waypoints: self.current_waypoint = 0 self.current_waypoint += 1 self.get_waypoint_angle() self.player.car.angle = self.angle self.player.car.rotate() self.player.move() 

El caso es que cuando configuro el ángulo del automobile en function del retorno de la function self.player.car.angle = self.angle , self.player.car.angle = self.angle , el automobile gira / gira de manera extremadamente poco realist. Funciona, pero significa que tengo que dirigir gradualmente el automobile, y luego me enfrento a este problema. No sé cuándo girar a la izquierda o a la derecha, porque el ángulo puede ser negativo. Si hago esto, por ejemplo:

  if self.player.car.angle > self.new_angle: self.player.car.angle -= self.player.car.steering_speed else: self.player.car.angle += self.player.car.steering_speed 

El robot conduce al siguiente destino del punto de reference al conducir extrañamente en círculos.

Problema

Por lo tanto, sé la dirección en la que debería conducir el robot, pero en function de su ángulo anterior, no sé si debería dirigirse hacia la izquierda o hacia la derecha para llegar a esa dirección.

Me saltaría la trigonometría directamente y usaría un truco vectorial en 2D que nos permite verificar la dirección izquierda / derecha con una simple sum y multiplicación.

Aquí tendría su automobile almacenar su dirección hacia adelante como un vector de unidad 2D, car.forward (que de todos modos podría estar utilizando para calcular su velocidad), entonces:

 // Compute the offset from the car to the waypoint, as you have now. self.dx = self.track.waypoint_positions[self.current_waypoint][0] - self.player.car.pos[0] self.dy = self.track.waypoint_positions[self.current_waypoint][1] - self.player.car.pos[1] // Form the dot product of this offset with the perpendicular // to the forward vector: (forward.y, -forward.x) self.side = self.dx * self.car.forward[1] - self.dy * self.car.forward[0] // If this dot product is negative, the destination is on one side... if self.side < 0: self.player.car.angle -= self.player.car.steering_speed // ...otherwise it's on the other (or dead ahead if the value is close to 0) else: self.player.car.angle += self.player.car.steering_speed 

Los signos pueden voltearse dependiendo de las convenciones de su sistema de coorderadas (y arriba vs y abajo / angularjs medidos en sentido horario o antihorario)

Sospecho que la lógica problemática está aquí:

  if self.player.car.angle > self.new_angle: self.player.car.angle -= self.player.car.steering_speed else: self.player.car.angle += self.player.car.steering_speed 

No se puede decir si se debe girar a la izquierda o a la derecha simplemente debido a la comparación ordinal ( < o > ) porque los angularjs podrían estar cerca de pi, y la discontinuidad allí lo ensucia (por ejemplo, si actualmente está en el rumbo 3, y el ángulo objective es -3, este código te indica que debes girar en el sentido de las agujas del reloj (delta del ángulo negativo), mientras que realmente solo quieres dirigirte hacia 3.28 [que es equivalente a -3])

Quieres algo más como

 # angle_to_steer is now our angle difference, chosen so that it's between -pi and pi angle_to_steer = (self.new_angle - self.player.car.angle + pi) % (2 * pi) - pi if angle_to_steer < 0: self.player.car.angle -= self.player.car.steering_speed else: self.player.car.angle += self.player.car.steering_speed