# Obstacle Avoidance With Walls in C#

I'm trying to do some obstacle avoidance. Yet somehow something is not going quite well. I've used the book "Programming Game AI by Example" to create a simular function in c# in combination with XNA.

This is what i'm doing right now:

public Vector2 ObstacleAvoidance(List<Obstacle> obstacles)
{
//the detection box length is proportional to the agent's velocity
Owner.DetectionBox = Owner.MinDetectionBoxLength +
((Owner.Speed() / Owner.MaxSpeed) * Owner.MinDetectionBoxLength);
//tag all obstacles within range of the box for processing
TagObstaclesWithinViewRange(Owner);

//this will keep track of the closest intersecting obstacle (CIB)
BaseGameEntity ClosestIntersectingObstacle = null;

//this will be used to track the distance to the CIB
double DistToClosestIP = Double.MaxValue;

//this will record the transformed local coordinates of the CIB
Vector2 LocalPosOfClosestObstacle = new Vector2();

foreach (Obstacle curOb in obstacles)
{
//if the obstacle has been tagged within range proceed
if (curOb.Tag)
{
//calculate this obstacle's position in local space
Vector2 LocalPos = HelperMethods.PointToLocalSpace(curOb.Position,
Owner.Side,
Owner.Position);

//if the local position has a negative x value then it must lay
//behind the agent. (in which case it can be ignored)
if (LocalPos.X >= 0)
{
//if the distance from the x axis to the object's position is less
//than its radius + half the width of the detection box then there
//is a potential intersection.
if (Math.Abs(LocalPos.Y) < ExpandedRadius)
{
//now to do a line/circle intersection test. The center of the
//circle is represented by (cX, cY). The intersection points are
//given by the formula x = cX +/-sqrt(r^2-cY^2) for y=0.
//We only need to look at the smallest positive value of x because
//that will be the closest point of intersection.
double cX = LocalPos.X;
double cY = LocalPos.Y;

//we only need to calculate the sqrt part of the above equation once
double SqrtPart = Math.Sqrt(ExpandedRadius * ExpandedRadius - cY * cY);

double ip = cX - SqrtPart;

if (ip <= 0.0)
{
ip = cX + SqrtPart;
}

//test to see if this is the closest so far. If it is keep a
//record of the obstacle and its local coordinates
if (ip < DistToClosestIP)
{
DistToClosestIP = ip;

ClosestIntersectingObstacle = curOb;

LocalPosOfClosestObstacle = LocalPos;
}
}
}
}
}

//if we have found an intersecting obstacle, calculate a steering
//force away from it
Vector2 SteeringForce = Vector2.Zero;

if (ClosestIntersectingObstacle != null)
{
//the closer the agent is to an object, the stronger the
//steering force should be
double multiplier = 1.0 + (Owner.DetectionBox - LocalPosOfClosestObstacle.X) /
Owner.DetectionBox;

//calculate the lateral force
SteeringForce.Y = (float) ((ClosestIntersectingObstacle.BoundingRadius -
LocalPosOfClosestObstacle.Y) * multiplier);

//apply a braking force proportional to the obstacles distance from
//the vehicle.
double BrakingWeight = 0.2;

SteeringForce.X = (float) ((ClosestIntersectingObstacle.BoundingRadius -
LocalPosOfClosestObstacle.X) *
BrakingWeight);
}

//finally, convert the steering vector from local to world space
return HelperMethods.VectorToWorldSpace(SteeringForce,
Owner.Side);
}


When i'm seeing the wall i still go through it instead of changing directions. This has something to do with this specific line of code:

double ExpandedRadius = curOb.BoundingRadius + Owner.BoundingRadius;
if (Math.Abs(LocalPos.Y) < ExpandedRadius)


When i'm seeing the wall i should go into this if yet i'm not, and therefore going through the wall.

curOb = the wall and his boudingradius is 12.5. Owner = the player and his bounding radius is also 12.5. The LocalPos.Y value is something like 120 which is correct as the y position of the wall is at that exact location. How can i try to fix this so my player won't crash into walls?

Greets

EDIT

The Promised Picture - It should detect the wall and add it to closestIntersectionObstacle but it doesnt

• So if I'm reading this right, LocalPos is the wall's position relative to the player. But then you say the Y value is 120. If the wall is 120 units away from the player and the bound is only 25, why are you expecting it to detect a possible collision? Jun 26 '14 at 14:52
• @Tesserex i will upload a photo for more detail in half an hour it'll describe what i think. In words: localpos.Y is the position in the world.. not relative to the player.. Jun 26 '14 at 14:55

As per your comment my reading was wrong. I thought LocalPos was relative to the player, because I assumed that's what HelperMethods.PointToLocalSpace was supposed to be doing. But if LocalPos is still world coords, then your description at the end of the question gives it away.

if (Math.Abs(LocalPos.Y) < ExpandedRadius)


can be translated into English like so:

if the wall's vertical position on the screen is less than the bounding distance...


Comparing an absolute position to a relative distance shouldn't make much sense intuitively.

It should be asking if the distance between the player and the wall is less than ExpandingRadius.

double playerDistance = /* Calculate distance between player and wall */
if (playerDistance < ExpandedRadius)

• I've got it sort of working, yet now it doesn't work with the detectionbox but instead the playersDistance so i should just change that, and i'm done thanks man! Jun 26 '14 at 16:50