SOLVED Shorter rotate direction

Hello, I am using mouse to set direction for my object (specifically direction, not image_angle) and I need to figure out shorter way for rotation.
I tried formula direction += sin(degtorad(target_direction - direction)) * rspeed; but I need object rotate at constant speed.
Below is my attempt. As a result only 1st mouse click rotates object to correct angle, all following clicks makes object rotate infinitely. Any ideas please?

GLOBAL RIGHT PRESSED EVENT:
GML:
dir = point_direction(x, y, mouse_x, mouse_y);
if dir < 180
{
    turn_direction = "Left";
    turn_amount = floor(dir / turn_speed)
    turn_last = dir % turn_speed
    show_debug_message(string(dir))
    show_debug_message(string(turn_amount))
    show_debug_message(string(turn_last))
}
else
{
    turn_direction = "Right";
    turn_amount = floor((360 - dir) / turn_speed)
    turn_last = (360 - dir) % turn_speed
    show_debug_message(string(dir))
    show_debug_message(string(turn_amount))
    show_debug_message(string(turn_last))
}
STEP EVENT:
GML:
if direction != dir
{
    if turn_counter != turn_amount
    {
        if turn_direction == "Left"
        {
            direction += turn_speed;
            image_angle = direction;
        }
        else
        {
            direction -= turn_speed;
            image_angle = direction;
        }
        turn_counter++;
    }
    else
    {
        if turn_direction == "Left"
        {
            direction += turn_last;
            image_angle = direction;
        }
        else
        {
            direction -= turn_last;
            image_angle = direction;
        }
        turn_counter = 0;
    }
    show_debug_message(string(direction) + " / " + string(dir))
}
 
Use angle_difference to find the shorter rotation.
I've tried use this. Seems like it works, but I am still encountering infinite rotation after several clicks, which is strange. Debugger says its reaching targeted direction and should stop.

GLOBAL RIGHT PRESSED EVENT:
GML:
dir = point_direction(x, y, mouse_x, mouse_y);
turn_direction = sign(angle_difference(direction, dir)) * -1;
turn_amount = floor(abs(angle_difference(direction, dir) / turn_speed));
turn_last = abs(angle_difference(direction, dir) % turn_speed);
    
show_debug_message(string(dir))
show_debug_message(string(turn_amount))
show_debug_message(string(turn_last))
show_debug_message(string(angle_difference(direction, dir)))

STEP EVENT:
GML:
if direction != dir
{
    if turn_counter != turn_amount
    {
        direction += turn_speed * turn_direction;
        image_angle = direction;
        turn_counter++;
    }
    else
    {
        direction += turn_last * turn_direction;
        image_angle = direction;
        turn_counter = 0;
        show_debug_message(string(direction) + " / " + string(dir))
    }
}
 

FrostyCat

Member
Beware target jitter. Think about what would happen with your code if your direction is 3, your target is 0, and your turning speed is 4.

There needs to be a margin within which you snap directly to the target and stop. This is a backstop for all code that involves moving towards a target.
GML:
if (direction != dir)
{
    var diff = angle_difference(dir, direction);
    if (abs(diff) <= turn_speed)
    {
        direction = dir;
    }
    else
    {
        direction += sign(diff)*turn_speed;
    }
}
image_angle = direction;
 
Beware target jitter. Think about what would happen with your code if your direction is 3, your target is 0, and your turning speed is 4.

There needs to be a margin within which you snap directly to the target and stop. This is a backstop for all code that involves moving towards a target.
GML:
if (direction != dir)
{
    var diff = angle_difference(dir, direction);
    if (abs(diff) <= turn_speed)
    {
        direction = dir;
    }
    else
    {
        direction += sign(diff)*turn_speed;
    }
}
image_angle = direction;
Hello, thanks for reminding, but I already handled this part with turn_last = abs(angle_difference(direction, dir) % turn_speed); As I said, its randomly can pass targeted direction and loop, yet it precisely hit required angle. Adjusted my code a little to demonstrate debugger, you can see there it worked fine 3 times and the 4th mouse click made it loop and every 20 turns display angle. I can't see pattern tbh, either not direction or angle.
EDIT: turn_speed = 3

GLOBAL RIGHT PRESSED EVENT:
GML:
dir = point_direction(x, y, mouse_x, mouse_y);
turn_direction = sign(angle_difference(direction, dir)) * -1;
turn_amount = floor(abs(angle_difference(direction, dir) / turn_speed));
turn_last = abs(angle_difference(direction, dir) % turn_speed);
   
show_debug_message("Target Direction: " + string(dir))
show_debug_message("Amount of turns: " + string(turn_amount))
show_debug_message("Remaining turn: " + string(turn_last))
show_debug_message("Angle difference: " + string(angle_difference(direction, dir)))
STEP EVENT:
GML:
if direction != dir
{
    if turn_counter != turn_amount
    {
        direction += turn_speed * turn_direction;
        image_angle = direction;
        turn_counter++;
    }
    else
    {
        direction += turn_last * turn_direction;
        image_angle = direction;
        turn_counter = 0;
        show_debug_message("Angle after all turns: " + string(direction) + " / " + string(dir))
        show_debug_message("===========================")
    }
}
DEBUGGER:
Code:
Entering main loop.
**********************************.
Target Direction: 293.39
Amount of turns: 22
Remaining turn: 0.61
Angle difference: 66.61
Angle after all turns: 293.39 / 293.39
===========================
Target Direction: 248.68
Amount of turns: 14
Remaining turn: 2.70
Angle difference: 44.70
Angle after all turns: 248.68 / 248.68
===========================
Target Direction: 353.05
Amount of turns: 34
Remaining turn: 2.36
Angle difference: -104.36
Angle after all turns: 353.05 / 353.05
===========================
Target Direction: 55.78
Amount of turns: 20
Remaining turn: 2.74
Angle difference: -62.74
Angle after all turns: 55.78 / 55.78
===========================
Angle after all turns: 118.52 / 55.78
===========================
Angle after all turns: 181.26 / 55.78
===========================
Angle after all turns: 244.00 / 55.78
===========================
Angle after all turns: 306.73 / 55.78
===========================
 
The problem still persist, but I figured out that angles without fractions always works fine. I can use only whole numbers, but anyone got explanation whats wrong with fractions?
 
Top