Legacy GM Smooth rotation problem

R

risa401

Guest
Hello! I got a little problem with my smooth rotation code.

Code:
Code:
var _pointDir = point_direction(x, y, x + lengthdir_x(16, direction), y + lengthdir_y(16, direction));
legAngle += sin(degtorad(_pointDir - legAngle)) * legAngleSpeed;
What happens:
Let's say the angle is 180 and now I want to turn to angle 0. Never will happen (unless I move it to a number not opposite to the opposite side [confusing I know]), I know that. How do I make it able to do that?

Thanks!
GIF: http://imgur.com/a/EjGJZ
 
Last edited by a moderator:

Nux

GameMaker Staff
GameMaker Dev.
Could you please upload a gif if this in action, or supply more code?

Also, wouldn't this:
Code:
var _pointDir = point_direction(x, y, x + lengthdir_x(16, direction), y + lengthdir_y(16, direction));
Just be the same as:
Code:
var _pointDir = direction;
?
 
R

risa401

Guest
Could you please upload a gif if this in action, or supply more code?

Also, wouldn't this:

Just be the same as:
Code:
var _pointDir = direction;
?
yes yes haha I copy pasted my code that needed that length from there :D Thanks xD
Personally I would sure need a gif to understand what you need to do there
Uploading right now check for the gif in roughly 5 mins
 
R

risa401

Guest
GIF: http://imgur.com/a/EjGJZ

The thing you want to watch is those two rectangles (legs). The are supposed to be faced the direction you are going. You can see that I'm showing when I'm rotating 180 degrees instantly. That makes the angle stuck and will move only after I go little bit to a different direction (so it's not the OPPOSITE of the OPPOSITE SIDE) :D

PS: Watch it a few times it's confusing I know :D
 

FrostyCat

Redemption Seeker
You forgot that sin(pi) is 0, make it so that it doesn't reach that point.
Code:
var _diff = angle_difference(legAngle, direction);
var _turn = sin(degtorad(_diff/2)) * legAngleSpeed;
if (abs(_turn) <= abs(_diff)) {
  legAngle += _turn;
}
else {
  legAngle = direction;
}
Edit: Changed to angle_difference().
 

Nux

GameMaker Staff
GameMaker Dev.
Ah!

The cause of your problem is the fact that sin(0-180) = 0.
This means you're technically doing:
Code:
legAngle += 0;
You could fix this by offsetting the angle so it's barely just 180, but not exactly 180
 
R

risa401

Guest
I know that, don't worry. I'll try that tommorow I have no time today.

You forgot that sin(pi) is 0, make it so that it doesn't reach that point.
Code:
var _diff = angle_difference(legAngle, direction);
var _turn = sin(degtorad(_diff/2)) * legAngleSpeed;
if (abs(_turn) <= abs(_diff)) {
  legAngle += _turn;
}
else {
  legAngle = direction;
}
Edit: Changed to angle_difference().
works but when I stop it dances like hell :D Will try to fix tommorow!!
 

FrostyCat

Redemption Seeker
direction automatically resets to 0 when you set the speed back to 0, create your own direction variable and use that instead.
 
I

icuurd12b42

Guest
var _pointDir = point_direction(x, y, x + lengthdir_x(16, direction), y + lengthdir_y(16, direction));
legAngle += sin(degtorad(_pointDir - legAngle)) * legAngleSpeed;

sin(degtorad(_pointDir - legAngle)) * legAngleSpeed;
dsin(_pointDir - legAngle) * legAngleSpeed;
or
lengdir_y(legAngleSpeed,_pointDir - legAngle)...

To prevent the lock when the 2 directions are exactly opposite, as suggested you can use angle_difference, but cap the result...
adif = angle_difference(direction,legAngle );
adif = clamp(adif,-179,179);
legAngle += lengdir_y(legAngleSpeed,adif)...

this should make it work like you initially intended. That is, slow to start turning, then fast turning when perpendicular, then slow to stop...

Note, I may have reversed the angles for the parameters in angle_difference
 
R

risa401

Guest
direction automatically resets to 0 when you set the speed back to 0, create your own direction variable and use that instead.
That was not the problem.

var _pointDir = point_direction(x, y, x + lengthdir_x(16, direction), y + lengthdir_y(16, direction));
legAngle += sin(degtorad(_pointDir - legAngle)) * legAngleSpeed;

sin(degtorad(_pointDir - legAngle)) * legAngleSpeed;
dsin(_pointDir - legAngle) * legAngleSpeed;
or
lengdir_y(legAngleSpeed,_pointDir - legAngle)...

To prevent the lock when the 2 directions are exactly opposite, as suggested you can use angle_difference, but cap the result...
adif = angle_difference(direction,legAngle );
adif = clamp(adif,-179,179);
legAngle += lengdir_y(legAngleSpeed,adif)...

this should make it work like you initially intended. That is, slow to start turning, then fast turning when perpendicular, then slow to stop...

Note, I may have reversed the angles for the parameters in angle_difference
Works beautifully! Thanks! I grabbed this piece of code from one tutorial because I don't really get all the sin, degtorad stuff for now :D I guess it will be useful to learn it :D (In actual math, I'm still in elementary school so they don't teach us that stuff :p)

PS: You reversed these numbers: clamp(adif, -179, 179) :D So it's clamp(adif, 179, -179). So yep you reversed it :D
 
I

icuurd12b42

Guest
Usually clamp expects (actual, minval, maxval)

Glad I could help
 
Top