public static Vector2 ChangeDirection(GameTime gameTime, Vector2 dir, Vector2 pos, Vector2 followedPos, double degreeChange) { double radians = RadiansFromDir(dir); double radianChange = degreeChange * (Math.PI / 180); Vector2 dirToFollowed = new Vector2(followedPos.X - pos.X, followedPos.Y - pos.Y); dirToFollowed = MathFunctions.ScaleDirection(dirToFollowed); double dirFolRadians; if (dirToFollowed.Y > 0) { dirFolRadians = Math.Acos(dirToFollowed.X); } else { dirFolRadians = 2 * Math.PI - (Math.Acos(dirToFollowed.X)); } if (dirFolRadians > 2 * Math.PI) { dirFolRadians -= 2 * Math.PI; } double deltaRadians = MathFunctions.DeltaRadians(radians, dirFolRadians); // If target angle is closer to current than the given delta angle, assign target angle if (Math.Abs(deltaRadians) < Math.Abs(radianChange)) { radians = dirFolRadians; } // If not, increment current angle by given delta angle else { var fpsCompensatedRadianChange = radianChange * MathFunctions.FPSSyncFactor(gameTime); if (deltaRadians > 0 && deltaRadians <= 180) { radians += fpsCompensatedRadianChange; } else if (deltaRadians < 0 && deltaRadians <= 180) { radians -= fpsCompensatedRadianChange; } else if (deltaRadians > 0 && deltaRadians > 180) { radians -= fpsCompensatedRadianChange; } else //(dirFolRadians < Radians && (dirFolRadians - Radians) > 180) { radians += fpsCompensatedRadianChange; } } Vector2 newDir = Vector2.Zero; newDir.X = (float)(Math.Cos(radians)); newDir.Y = (float)(Math.Sin(radians)); return(newDir); }