# How to circle a target at a constant distance

I have an AI ship that stops approaching when it gets within firing range, and starts strafing around its target. The problem is that it doesn't circle its target very well. The following code attempts to do this, and for short periods of time, it's convincing, but as soon as you let it run for ~5-10 seconds, the AI ship drifts out of range of the target and is forced into the approach state again.

``````Vector2 tangent = Vector2.Normalize(new Vector2(TargetVector.Y, -TargetVector.X));
velocity += 0.8f * tangent * accelerationMagnitude * (float)gameTime.ElapsedGameTime.TotalSeconds;
velocity += 0.2f * TargetVector * accelerationMagnitude * (float)gameTime.ElapsedGameTime.TotalSeconds;
``````

The above doesn't work for obvious reasons, so I attempted to bring the target into my frame of reference using the following:

``````Vector2 tangent = new Vector2(TargetVector.Y, -TargetVector.X);
Vector2 asdf = tangent + (velocity * (float)gameTime.ElapsedGameTime.TotalSeconds);
velocity += Vector2.Normalize(asdf) * accelerationMagnitude * (float)gameTime.ElapsedGameTime.TotalSeconds;
``````

Here is a quick video on how it behaves using the second method while trying to maintain a firing distance of 350: https://www.youtube.com/watch?v=16Bc46ekJI0 The white line and number indicate the Ship->Station vector and distance, and red circles are the weapon ranges.

How do I make my AI ship circle its prey convincingly?

-

Rather than attempting to calculate acceleration so that the physics system will generate the desired motion, it's probably better to calculate the desired motion directly, like

``````angle += rotationRate * (float)gameTime.ElapsedGameTime.TotalSeconds;
You can then apply some type of steering behavior so that the AI ship will attempt to stay on top of `desiredPos`. Or, simply set the AI ship's position to `desiredPos` if it's close enough. You can calculate velocity and acceleration by taking derivatives of `desiredPos` if you need them for other reasons (for instance, showing thruster sprites based on acceleration).
If your ship gets too far from the target, you can switch off this behavior; and in the approach phase, you can set `angle` based on the angle your ship is coming in from, so the `desiredPos` will be in the right place when the circling behavior switches on.
Much better now. I used a `desiredPosition` with a steering algorithm to get it to orbit: i.stack.imgur.com/Sf7kO.gif Thanks! – John McDonald May 8 '14 at 4:20