Smoothly rotate to face the cursor
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Smoothly rotate to face the cursor
I would like a moving objects to gradually rotate towards the mouse. I can get it to move towards the mouse easily, but this is not what I want. I've been trying for a while and just can't seem to get it to work. I would be grateful for any help.
Re: Smoothly rotate to face the cursor
A function like this would work, with radians or whatever.
Not too sure, though. Wrote it from memory. This works for velocity, I assume it'd work for rotation somehow.
Code: Select all
function smooth(goal, current, dt)
local diff = goal - current --checking if there's a different between the goal and the current
if(diff>dt)then --this means that we still need to speed up
return current + dt
end
if(diff<-dt)then --and this means we need to slow down
return current - dt
end
return goal --if diff equals 0 then just return goal
end
Code: Select all
L
L Ö
Ö V
L Ö V E
Ö B E
V E
E Y
Re: Smoothly rotate to face the cursor
iPoisonxL's code is almost correct. One thing is missing, namely the two angles zero and 2pi are the same, even though the two numbers differ a lot. To determine whether to turn left or right, you need calculate diff as follows:
That way diff is always between -pi and pi.
Code: Select all
local diff = (goal-current+math.pi)%(2*math.pi)-math.pi
Check out my blog on gamedev
Re: Smoothly rotate to face the cursor
I thank you both for your help, I must have been pretty close as this is very similiar to something I tried doing. I've got it working now so thanks.
Re: Smoothly rotate to face the cursor
Sorry for bumping a somewhat old post, but could you explain to me how this formula works? It works, but I don't know why. It's really bugging me.micha wrote:iPoisonxL's code is almost correct. One thing is missing, namely the two angles zero and 2pi are the same, even though the two numbers differ a lot. To determine whether to turn left or right, you need calculate diff as follows:That way diff is always between -pi and pi.Code: Select all
local diff = (goal-current+math.pi)%(2*math.pi)-math.pi
Code: Select all
L
L Ö
Ö V
L Ö V E
Ö B E
V E
E Y
Re: Smoothly rotate to face the cursor
Sure.
Let's say we have the two angles "current" and "goal". We call the number, we get when we subtract them "plain difference" or "pd". It is between -2pi and 2pi (because each angle is between 0 and 2pi). And we call the desired output the "true difference" or "td". This should be a number between -pi and pi.
Have a look at the different possible values of the plain difference and the corresponding true difference.
Now for the formula: The modulo-operator "%" does exactly this: If you calculate a%b, then operator adds or subtracts b from a until the result is between 0 and b. Example: 20%7 = 6. 20 is not between 0 and 7, so we subtract: 20-7 = 13. Still not in the range, subtract once again: 13-7 = 6. In the range. Calculation finished.
Another example: -20%7 = 1. -20 is not in the range, so add 7 until you reach the range-> -13,-6,1.
In summary: The modulo-operator gives a result between zero and b and gets the result by adding or subtracting b as often as necessary.
If we now did this:
Then we would get a number between 0 and 2pi. But what we want is a number between -pi and pi (this is the same interval, but shifted by -pi). Thus we first shift the number by pi then do the modulo operator and then subtract pi again.
If this explanation is not clear enough, don't hesitate to ask again. Explaining this without figures is not easy.
Let's say we have the two angles "current" and "goal". We call the number, we get when we subtract them "plain difference" or "pd". It is between -2pi and 2pi (because each angle is between 0 and 2pi). And we call the desired output the "true difference" or "td". This should be a number between -pi and pi.
Have a look at the different possible values of the plain difference and the corresponding true difference.
- -pi to pi: If the plain difference is in this range, than it coincides with the true difference.
- pi to 2pi: In this case, the plain difference, is the larger of the two possible angles, between the two rays. We want to find the smaller one. The two add up to the full circle (2pi) and so we get: td = -(2pi - pd). The addition minus before the brackets correct the sign. Turning 270° to the left is the same as turning 90° to the RIGHT. We can reformulate the equation as td = pd - 2pi
- -2p to -pi: The same reasoning as in the case before: td = pd + 2pi.
Now for the formula: The modulo-operator "%" does exactly this: If you calculate a%b, then operator adds or subtracts b from a until the result is between 0 and b. Example: 20%7 = 6. 20 is not between 0 and 7, so we subtract: 20-7 = 13. Still not in the range, subtract once again: 13-7 = 6. In the range. Calculation finished.
Another example: -20%7 = 1. -20 is not in the range, so add 7 until you reach the range-> -13,-6,1.
In summary: The modulo-operator gives a result between zero and b and gets the result by adding or subtracting b as often as necessary.
If we now did this:
Code: Select all
td = pd % (2*math.pi)
Code: Select all
td = (pd + math.pi) % (2*math.pi) - math.pi
Check out my blog on gamedev
Re: Smoothly rotate to face the cursor
This makes sense, thanks a lot.
Code: Select all
L
L Ö
Ö V
L Ö V E
Ö B E
V E
E Y
Re: Smoothly rotate to face the cursor
Sorry for the bump, but I'm trying to make this work, where did you get 'goal' and 'current' and 'dt' from? Nil values... NIL VALUES EVERYWHERE...
while true do end;
Re: Smoothly rotate to face the cursor
You put that in the top of the code from the first reply in place of the original, I'm assuming, i.e.:
Code: Select all
function smooth(goal, current, dt)
local diff = (goal-current+math.pi)%(2*math.pi)-math.pi
if(diff>dt)then --this means that we still need to speed up
return current + dt
end
if(diff<-dt)then --and this means we need to slow down
return current - dt
end
return goal --if diff equals 0 then just return goal
end
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
- zorg
- Party member
- Posts: 3465
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: Smoothly rotate to face the cursor
Those are parameters. You define them somewhere, and pass them to the function for it to work on.RonanZero wrote:Sorry for the bump, but I'm trying to make this work, where did you get 'goal' and 'current' and 'dt' from? Nil values... NIL VALUES EVERYWHERE...
not gonna give code (yet anyway), but:
goal - should be the angle (orientation) of your object towards your mouse's current position.
current - should be the current angle (orientation) of your object.
dt - a parameter used in love.update, since you should call the above smooth function inside that one, though you can get the value using love.timer.getDelta() elsewhere as well.
finally i am assuming you do have an object (like a table with fields like orientation, position, etc...), or at least an orientation variable to use.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 3 guests