Advertisement
ulfben

steering behaviors

Feb 21st, 2025 (edited)
429
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.82 KB | None | 0 0
  1. Vector2 arrive(Vector2 target) const noexcept {
  2.     Vector2 toTarget = target - position;
  3.     float distance = Vector2Length(toTarget);
  4.  
  5.     if (distance < 0.1f) return ZERO; // If already at target, no force needed
  6.  
  7.     float speed = globalConfig.max_speed;
  8.    
  9.     // Apply gradual deceleration within the arrive radius
  10.     if (distance < globalConfig.arrive_radius) {
  11.         speed = globalConfig.max_speed * (distance / globalConfig.arrive_radius);
  12.     }
  13.  
  14.     Vector2 desiredVelocity = Vector2Normalize(toTarget) * speed;
  15.     return (desiredVelocity - velocity) * globalConfig.arrive_weight;
  16. }
  17.  
  18. Vector2 pursuit(const Boid& target) const noexcept {
  19.     Vector2 toTarget = target.position - position;
  20.     float distance = Vector2Length(toTarget);
  21.  
  22.     // Estimate time to intercept based on distance and relative speed
  23.     float lookAheadTime = distance / (globalConfig.max_speed + Vector2Length(target.velocity));
  24.  
  25.     // Predict future target position
  26.     Vector2 futurePosition = target.position + (target.velocity * lookAheadTime);
  27.  
  28.     // Seek the predicted position instead of current position
  29.     return seek(futurePosition);
  30. }
  31.  
  32. Vector2 evade(const Boid& pursuer) const noexcept {
  33.     Vector2 toPursuer = pursuer.position - position;
  34.     float distance = Vector2Length(toPursuer);
  35.  
  36.     // Compute lookahead time based on both speeds
  37.     float lookAheadTime = distance / (globalConfig.max_speed + Vector2Length(pursuer.velocity));
  38.  
  39.     // Predict future position of the pursuer
  40.     Vector2 futurePosition = pursuer.position + (pursuer.velocity * lookAheadTime);
  41.  
  42.     // Steer away from the predicted position
  43.     return flee(futurePosition);
  44. }
  45.  
  46. struct Config {
  47.     float wander_distance = 50.0f; // Distance ahead of the boid to project the wander circle
  48.     float wander_radius = 25.0f;    // Size of the wander circle
  49.     float wander_jitter = 0.2f;     // How much the wander angle changes each frame
  50.     float wander_weight = 0.5f;     // Steering force weight for wander behavior
  51. };
  52. float wanderAngle = 0.0f; // Persistent wandering angle
  53.  
  54. Vector2 wander() noexcept {
  55.     // Step 1: Project the wander circle ahead of the boid
  56.     Vector2 circleCenter = Vector2Normalize(velocity) * globalConfig.wander_distance;
  57.  
  58.     // Step 2: Adjust the wander angle slightly
  59.     wanderAngle += unit_range() * globalConfig.wander_jitter; // Small random variation
  60.  
  61.     // Step 3: Compute displacement on the wander circle (ensuring uniform distribution)
  62.     Vector2 displacement = {
  63.         cos(wanderAngle) * globalConfig.wander_radius,
  64.         sin(wanderAngle) * globalConfig.wander_radius
  65.     };
  66.  
  67.     // Step 4: Calculate the final wander target
  68.     Vector2 wanderTarget = position + circleCenter + displacement;
  69.  
  70.     // Step 5: Seek the wander target
  71.     return seek(wanderTarget) * globalConfig.wander_weight;
  72. }
  73.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement