[Solved] Smooth transition between angles

Hey guys,

I trying to create some simple AI for my enemy class. I have an enemy moving 0 degrees initially, and I want to make him move smoothly to angle 270 (straight down in my coordinate system). How can this be done?

With my current code, he ends up “taking the long way around” so to speak but it works fine for transitioning from 180 to 270 (left to down). I’m looking for something that will transition smoothly no matter what the chosen direction is and preferably so he would take the shortest route to get there.

This seems like it should be simple, but it’s driving me nuts! I am posting my code below which doesn’t quite work. In the below example, the variable direction is fixed at 270.


public void doBehavior(GameObject g)
	{
		int currentDirection = g.getDirection();
		
		// Smooth transition from current direction to new
		
		
		if(currentDirection < direction)
		{
			g.setDirection(currentDirection + 1);
		}
		
		else if(currentDirection > direction)
		{
			g.setDirection(currentDirection - 1);
		}
		
	}

you could calculate the clockwise and anticlockwise difference between currentdirection and direction. taking into account that it will go from 360deg to 0deg either way. if the result is < 0 then add 360, if its > 360 subtract 360.

then which ever is the smaller difference is which way to turn.

Ok here is what I have so far:


	public void doBehavior(GameObject g)
	{
		int currentDirection = g.getDirection();
		int diff1 = currentDirection - direction;
		int diff2 = direction - currentDirection;
		
		if(diff1 < 0) diff1 += 360;
		else if(diff1 > 360) diff1 -= 360;
	
		if(diff2 < 0) diff2 += 360;
		else if(diff2 > 360) diff2-= 360;
		
		// Now what do I do with these numbers?
		
	}

if diff1 < diff2 then turn left, else turn right (it could be opposite though ;P)

I get what you’re saying, but my movement is based on sin and cos, so how would this look in code? The only way I can see is to either add or subtract from the currentDirection which works if he’s moving left but not for moving right. ??

what causes it to not work? i think you need to do another check after turning, to make sure your current direction hasnt gone below 0 or above 360

In your last post you said: if diff1 < diff2 then turn left, else turn right (it could be opposite though ;P). But what do you mean by turn left? Do I add to the currentDirection?

if you change part of your original code to this, it should be close to working

[quote] if(diff1 < diff2)
{
g.setDirection(currentDirection + 1);
}

  else if(diff1 > diff2)
  {
     g.setDirection(currentDirection - 1);
  }

[/quote]

Hmmm this makes him turn and go up. I tried reversing the plus and minus but he just does a loop. God I wish I’d studied trig in school…

yeah i cant remember trig so well right now. i just looked up some old code which does what you want (not in java) but its so poorly written i cant understand it, all the variables are a,b,c, etc :frowning:

Thanks for trying. I guess I’ll keep playing around and see what I can come up with.

After some playing around, I might have something that works. At least for transitioning from 0 to 270 and then from 180 back to 270. Haven’t tried other angles yet but here it is for those that are interested.


public void doBehavior(GameObject g)
	{
		int currentDirection = g.getDirection();
	    
		if(currentDirection == 0) currentDirection = 360;
		
		if(currentDirection < direction)
		{
			g.setDirection(currentDirection + 1);
		}
		
		else if(currentDirection > direction)
		{
			g.setDirection(currentDirection - 1);
		}
		
	}

oh i see. the angle range is -90 to 270 is it?? i was assuming the range is from 0-360.

Yeah the one thing I hate about libgdx. Getting used to that fact that Y is up!

That’s kind of standard for most graphics environments…

if this doesnt help, im going back to sleep.


      if(diff1 < -90) diff1 += 360;
      else if(diff1 > 270) diff1 -= 360;
   
      if(diff2 < -90) diff2 += 360;
      else if(diff2 > 270) diff2-= 360;

Rest well sir. What I have is working flawlessly for my little space shooter project. Like I said, I haven’t tried every angle yet, but it seems to work for what I need. Marking this one solved.

If you kept everything as vectors, it’d be a lot neater.
You’d just examine the sign of the determinant (cross product) of the 2 vectors to know if one is to the left, or right of the other.

pseudo code something like:


determinant = (b.x - a.x)*(c.y - a.y) - (b.y - a.y)*(c.x - a.x);
if(determinant>0) turnLeft();
else if(determinant<0) turnRight();
else fire();