   Orienting a Ship With the Right Stick, Part II
Quote:Original post by Atrix256PPS - if you want to make your game feel more sophisticated, instead of setting the angle to the angle on the stick, interpolate the current angle to the angle of the stick... IE move the current angle to the destination angle over time (a small amount of time like 1/10th of a second). This will give it a more polished feeling and if the interpolation time is short enough it shouldn't interfere with game play.I just started trying to do this (mostly for enemy aiming/movement), but I've run into a problem while trying to make the player do this. I was trying to make it turn either clockwise or counterclockwise depending on which would be faster, and it mostly works. However, when the angle is between pi and pi/2, and I aim toward an angle between pi and 3pi/2, I rotate clockwise when I should rotate counterclockwise. I can't figure out why.   
  arctan2 normally returns an angle between -pi to pi. So if your target angle is "3pi/2", internally it may be -pi. Depending on the logic in your program, it might consider that to the right of your ship.   ;  Huh. I assumed the radians in XNA were the same as what I was taught in math class:......pi/2........|...pi-----0 or 2pi........|.....3pi/2I guess I have a lot to learn.[Edited by - Lunar180 on May 26, 2010 1:50:36 PM];  Re:You could write a function that determines whether the target is on your left or right.Example 1:Suppose A's orientation is pi, and B's orientation is 3pi/2, and you want to know whether B is on the left of A. Therefore, you perform:B.ori - A.ori = pi/2Once you get this answer, you make sure that it is an angle between -pi and pi. If it is greater than pi, you substract 2pi from it. If it is less than -pi, you add 2pi to it. You do this trimming function:trim(pi/2) = pi/2Since pi/2 is positive, B is on the left of A.Example 2:A.ori = piB.ori = -pi/2B.ori - A.ori = -3pi/2trim(-3pi/2) = pi/2Since pi/2 is positive, B is on the left of A.;  Okay, so here is my redone method. The parameters are the y and x values of the right stick's position. Angle is the current orientation of the ship.protected void aimShip(float y, float x)   {  angle = (float)(Math.Atan2((double)y, (double)x) + ((2 * Math.PI) / 4));  float targetAngle = (float)(Math.Atan2((double)y, (double)x) + ((2 * Math.PI) / 4));  float difference = targetAngle - angle;  if (difference > Math.PI)  { difference -= (float)(2 * Math.PI);  }  else if (difference < -Math.PI)  { difference += (float)(2 * Math.PI);  }  if (difference > 0)  { angle += turnSpeed;  }  else if (difference < 0)  { angle -= turnSpeed;  }  else  { angle = targetAngle;  }   }I currently cannot test this myself. If anyone sees something wrong with my code, let me know. I should be able to test this soon.   ;  I think you need to use a different variable name for the other ship.angle = (float)(Math.Atan2((double)y, (double)x) + ((2 * Math.PI) / 4));targetAngle should be calculated based on the vector from yourself to the target.selfToTargetX = TargetX - SelfXselfToTargetY = TargetY - SelfYtargetAngle = atan2( selfToTargetY, selfToTargetX )In your if statements for updating Angle, the comparisons should be done with turnSpeed instead of 0:if (difference > turnspeed) {  angle += turnspeed;}else if(difference < turnspeed){  angle -= turnspeed;}else{  angle = turnspeed;}   