Sunday, November 26, 2017

c# - When a sprite is rotating to follow an angle, how to prevent it from reversing direction after a point?


Below is a section of my code which handles a player's sprite rotating towards an angle after a user touches the screen:


touchState = TouchPanel.GetState();

Vector2 touchPosition;

if (touchState.Count > 0)
{
touchPosition = new Vector2(touchState[0].Position.X, touchState[0].Position.Y);
targetPosition = Math.Atan2(player.Position.X - touchPosition.X, player.Position.Y - touchPosition.Y);

if (angle_radians < targetPosition)
{
angle_radians += 2 * fps;

}

if(angle_radians > targetPosition)
{
angle_radians -= 2 * fps;
}

player.Angle = angle_radians * -1;
}


The problem I'm having is that when the angle goes past a certain point (I believe 3.15 radians?), the logic no longer functions correctly and the sprite reverses direction in a 360 circle until it meets the target position again.


I know there is something I'm missing from this logic, and I can see the problem, but I'm not sure how to approach handling it.


How would I prevent the sprite from reversing direction?


Thanks


EDIT: I tried the solution below but I only receive a positive number from 0-6 for angle_distance, what have I done wrong?


            if (touchState.Count > 0)
{
touchPosition = new Vector2(touchState[0].Position.X, touchState[0].Position.Y);
targetPosition = Math.Atan2(player.Position.X - touchPosition.X, player.Position.Y - touchPosition.Y);
angle_distance = targetPosition - angle_radians + Math.PI;

angle_distance = angle_distance - Math.Floor(angle_distance / 2 / Math.PI) * 2 * Math.PI;

if (angle_distance < 0)
{
angle_radians -= 2 * fps;
}

if (angle_distance > 0)
{
angle_radians += 2 * fps;

}

player.Angle = angle_radians * -1;
}

EDIT: I now realise my mistake, correct solution is below


if (touchState.Count > 0)
{
touchPosition = new Vector2(touchState[0].Position.X, touchState[0].Position.Y);
targetPosition = Math.Atan2(player.Position.X - touchPosition.X, player.Position.Y - touchPosition.Y);


angle_distance = targetPosition - angle_radians + Math.PI;
angle_distance = angle_distance - Math.Floor(angle_distance / 2 / Math.PI) * 2 * Math.PI;

if (angle_distance < Math.PI)
{
angle_radians -= 2 * fps;
}

if (angle_distance > Math.PI)

{
angle_radians += 2 * fps;
}

player.Angle = angle_radians * -1;
}

Answer



First, find the signed distance between the two angles:


dist = targetAngle - currentAngle + pi
dist = dist - floor(dist / 2 / pi) * 2 * pi - pi


If it's negative, then subtract from the current angle to reach the other angle in the shortest time, if it's positive, then add to it.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...