Steering Behaviors: Obstacle Avoidance
- Steering Behaviors: Wander
- Steering Behaviors: Pursuit and Evade
- Steering Behavior: Fleeing
- Steering Behaviors: Seeking
- Steering Behaviors: Arrival
- Steering Behaviors: Obstacle Avoidance
- Steering Behaviors: Unaligned Collision Avoidance
- Steering Behaviors: Flow Field Following
- Steering Behaviors: Path Following
- Steering Behaviors: Flocking
The next post in the steering behaviors series is obstacle avoidance. We will be using the Vector2D.as and Vehicle.as files for this. If you don’t have them, you should get them. This behavior is based on Craig Reynold’s article Steering Behaviors For Autonomous Characters.
Obstacle Avoidance is used in order to have a vehicle move around an environment without running into objects. This is different from fleeing in one main way. If the vehicle is near a circle and it is not going to hit the circle, nothing is done. If the vehicle was fleeing the circle, it would turn and go directly away from the circle.
Because this isn’t collision detection, we don’t need super accurate shapes to define the obstacles. A bounding circle will be good enough.
Obstacle avoidance is similar to the Ray Casting method, you put out a line and determine if it is touching a circle. If it is, you steer around the circle. You only care about the closest circle. If your ray is long enough that it touches two circles, you only avoid the first one. By avoiding the first one, you are avoiding the second as well.
Now for some code:
private var checkLength:Number = 100;//the distance to look ahead for circles
public function avoidObstacles(circles:Array):void {
for(var i:int = 0; i < circles.length; i++) {//loop through the array of obstacles
var forward:Vector2D = velocity.cloneVector().normalize();//get the forward vector
var diff:Vector2D = circles[i].position.cloneVector().subtract(position);//get the difference between the circle and the vehicle
var dotProd:Number = diff.dotProduct(forward);//get the dot product
//this will be used for projection
//much like in the <a href="http://rocketmandevelopment.com/2010/05/19/separation-of-axis-theorem-for-collision-detection/">SAT</a>
if(dotProd > 0) { //if this object is in front of the vehicle
var ray:Vector2D = forward.cloneVector().multiply(checkLength); //get the ray
var projection:Vector2D = forward.cloneVector().multiply(dotProd); //project the forward vector
var dist:Number = projection.cloneVector().subtract(diff).length; //get the distance between the circle and vehicle
if(dist < circles[i].radius + width && projection.length < ray.length) {
//if the circle is in your path (radius+width to check the full size of the vehicle)
//projection.length and ray.length make sure you are within the max distance
var force:Vector2D = forward.cloneVector().multiply(maxSpeed); //get the max force
force.angle += diff.sign(velocity) * Math.PI / 2; //rotate it away from the cirlce
//PI / 2 is 90 degrees, vector's angles are in radians
//sign returns whether the vector is to the right or left of the other vector
force.multiply(1 - projection.length / ray.length); //scale the force so that a far off object
//doesn't drastically change the velocity
velocity.add(force);//change the velocity
velocity.multiply(projection.length / ray.length);//and scale again
}
}
}
}
Many vehicles avoiding circles
A vehicle avoiding while chasing the mouse
Sometimes you’ll see problems with warping across the edges. The vehicle can’t look across the edges, so it has no idea a circle is on the edge. It could be fixed, but I’ll leave that to you. Also, on the mouse one, sometimes the seeking behavior is stronger than the avoiding one so you’ll get some odd behavior where the vehicle will get “stuck” on a circle. This could be fixed by weighting the behaviors. We’ll look at this more in later posts.
| Print article | This entry was posted by rocketman on July 13, 2010 at 11:00 AM, and is filed under AI, AS3, Steering. Follow any responses to this post through RSS 2.0. You can leave a response or trackback from your own site. |









about 1 year ago
I have been on the lookout for a short time for a exceptional articles or blog posts involving this particular subject matter . Scouting around in Yahoo I eventually stumbled on this blog. Seeing this info I am truly satisfied to enunciate that I get a good impression I came across everything that I was looking for. Most definitely i’ll ensure to remember this website and take a look on a constant basis.