How to get to the corner that takes the shortest direction of rotation

I have a character in my game that needs to rotate smoothly in order to reach the desired angle. Consider angle

both the current angle and touchAngle

the desired angle, which is always between 0 and 360. I want to add + 1 / -1 to the current angle in every update of the game to get to the correct one touchAngle

. The problem is that the direction has to be chosen first and it has to be between 0 and 360. This is my pseudo code:

int touchAngle;
float angle;
public void update()
{
    if ((int)angle != touchAngle) angle += ???
}

      

+3


source to share


2 answers


Since you have values ​​that always normalize in the range [0 360]

, this shouldn't be too difficult. You just need to distinguish between two different cases:

angle < touchAngle
angle > touchAngle

      

in the first case we want to rotate counterclockwise, so there should be an update angle =+ 1

(assuming you want to rotate 1 every update cycle). In the second case, we want to rotate clockwise so that there is an update angle -= 1

.

The problem is that this is not always the shortest way to turn. For example, if:

angle == 359
touchAngle == 1

      



we don't want to fully use 358, 357, 356 ... instead we want to rotate counterclockwise in just 2 units: 360, 1. This can be achieved by comparing the distance between the corners abs(angle - touchAngle)

.

If this value is greater than 180

, it means that we are moving in the wrong way, so we need to make it so that

if(angle < touchAngle) {
    if(abs(angle - touchAngle)<180)
       angle += 1;
    else angle -= 1;
}

else {
    if(abs(angle - touchAngle)<180)
       angle -= 1;
    else angle += 1;
}

      

of course it's all up ((int)angale != touchAngle)

. I could be wrong in business, but this is a principle.

+5


source


Typically, you want to put time into the equation so that you can smoothly change the angle over time

. Most rigs have the ability to get the time it took to render the previous frame, and the typical way to do this is to say.

int touchAngle;
float angle;
float deltaTime; //Time it took to render last frame, typically in miliseconds
float amountToTurnPerSecond;
public void update()
{
    if((int)angle != touchAngle) angle += (deltaTime * amountToTurnPerSecond);
}

      

This will cause your angle to change by every second amountToTurnPerSecond

, but slowly change the correct amount of changes every frame to make it smooth. Something to note about this is that you usually end up evenly for touchAngle

most of the time, so it's best to check if you go and install instead touchAngle

.

Edit comment:

I think the easiest way to get the right direction of rotation is to not actually use corners. You need to get the relative direction from your touch to your character in 2nd place. Typically, you take a touch from screen space to world space and then do the calculations there (at least that's what I've done in the past). Start by getting your touch in world space, then use a vector cross-product to define the direction. It looks like this:

character position = cx, cy
target position = tx, ty
current facing direction of character = rx, ry

      



First, we take the distance between the character and the target position:

dx = tx - cx
dy = ty - cy

      

This not only gives us how far away it is from us, but essentially tells us that if we were at 0, 0, then which quadrant in 2d space would be the target?

Next, we do cross-product:

cross_product = dx * ry - dy * rx

      

If it is positive, you go one way, if it is negative, you go the other way. The reason this happens is because if the distance is, for example, (-5, 2)

then we know that if we are facing directly north, the point is on our left 5 and forward 2. So we turn left.

0


source







All Articles