I have a ship that travels at max speed maxSpeed and can turn rotationSpeed degrees per second. The ship always moves in the direction it is facing which means that the faster the ship is travelling the larger its turning radius is.

I know my position, and rotation and the target's position.

What I would like to figure out is whether a target is inside my turning radius at this speed, or better, what is the maximum speed I can travel at is in order to make the turn to the target without continually circling around it.

Is there an efficient(ish) way to do this?

Here is what I am thinking so far: because I know how far I am travelling per step and how much I am rotating per step, I can figure out where I will be in the next two frames. My current position is p1, my next position is p2 then p3. I can take the perpendicular bisectors of (p1, p2) and (p2, p3). Their intersection point will give me the center of a circle. I can then test if the target is in that circle.

I'm unsure if this will work in 3D (I'm unsure how to calculate a sphere with my inputs). This solution also doesn't help too much with finding the right speed at which to travel, I would have to try a few times with different speeds to find a reasonable one.

Can anyone shed some light on a better solution?


1 Answer 1


There are two ways an AI controlled unit with a bound rotation speed and an adjustable movement speed could reach a goal.

First, lets consider the challenge we are presented with so we could understand it better:

enter image description here

If the player is moving and rotating in constant speeds while trying to reach a goal that is on its right or left side, it will move in circles forever, never facing it's goal. The two areas that the player will circle are marked in red above.

The circular area marked in red can be computed like this:

radius = movementSpeed / rotationSpeedInRadians;
circlesCenterX = unitX + cos(unitAngle + / - PI) * radius;
circlesCenterY = unitY + sin(unitAngle + / - PI) * radius;

This results in the red circles' position and radius. We can use this to determine if a certain goal is outside the reach of the AI controlled unit if it continues to turn towards the goal's direction.

To find out if a certain item is within one of the circles, we simply calculate the distance from the circles's center:

if ((circleX - goalX)^2 + (circleY - goalY)^2 < radius^2) //goal is within red circle

There are two possible solutions for this:


Build up some distance until the goal is outside the circular red area and then turn around in a u-turn like fashion. This is simple, let the unit keep moving until the check returns that the goal is not within this circle. Then you can turn around.

enter image description here

The other option require a bit more work to compute:

We draw an imaginary line between the AI unit and the goal. Using the angle between them:

angle = Math.atan2(goalY - unitY, goalX - unitX);

Now you need to do the following in order to compute the correct speed:

correctSpeed = rotationSpeedInRadians * (distance / 2) / cos(angle);

enter image description here

In order to get it working in the 3d case:

Find the plane on which the following three points reside:

  1. The goal point.
  2. The position of the AI unit in the previous frame.
  3. The current position of the AI unit.

You could use that plane to compute the speed in the 2d way. You just need to convert the dots from their 3d values to the 2d values embedded on their common plane.

You might want to use this:

How to convert a 3D point on a plane to UV coordinates?

  • \$\begingroup\$ Perfect! Exactly the answer I was hoping for! Thanks for your detailed explanations, I think I am able to extrapolate on this and use it in 3D. \$\endgroup\$
    – weichsem
    Commented Apr 8, 2014 at 0:41
  • \$\begingroup\$ @weichsem I updated the answer. The idea I suggested is finding a common 2d plain they share and using it to compute the correct speed. \$\endgroup\$
    – AturSams
    Commented Apr 8, 2014 at 8:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .