How to make snap to angle rotation?

How do you make an object snap to angle when rotating to touch? That means for example, instead of a smooth continuous rotation, the object rotates in 45 degree intervals. >> 0°, 45°, 90°, 135°, 180°, 225°, 270°, 315°, 360°

Here’s my current code:

local myRect, start = display.newRect( display.contentCenterX, display.contentCenterY, 100, 300 ) local function rotate(e) if( e.phase == "began" ) then display.getCurrentStage():setFocus( myRect ) local dx = e.x - myRect.x local dy = e.y - myRect.y start = (math.atan2(dy,dx) \* 180 / math.pi) - myRect.rotation elseif( e.phase == "moved" ) then display.getCurrentStage():setFocus( myRect ) local dx = e.x - myRect.x local dy = e.y - myRect.y myRect.rotation = ( (math.atan2(dy,dx) \* 180 / math.pi) - start ) % 360 elseif( e.phase == "ended" ) then display.getCurrentStage():setFocus( nil ) end end myRect:addEventListener("touch", rotate)

I’m not sure what you mean but maybe you want to check what the angle of the object is and do something like -

if angle \<= 300 and angle \>= 359 then --object.rotation = 330-- end

–SonicX278 

That could work but it would require checking for every section of the 360 rotation, which seems like a really inefficient way to do it. Is there any other way?

Matters i guess. What/when are you trying to snap into a certain angle?

–SonicX278 

every 45° or 22.5°

So every time object is 45 or 22.5 you wan something to happen?

–SonicX278 

Yes, when the user rotates the object it should stick/ snap to the closest 45° angle. Like this: 0°, 45°, 90°, 135°, 180°, 225°, 270°, 315°, 360°

Ya so your best bet would be go with the way I showed above. That’s how i would do it. It should take no more than 5 min to code the whole thing to working properly. If you have problems doing it i can help no problem!

If someone has a better way i’d be glad to learn something new or refresh my memory!

I just realized that yes there is another way but it will be complicated and will take longer and include doing calculations. Which is really unnecessary.

–SonicX278 

You can work out which 45 degree increment you are closest to, rather than having lots of if statements:

--this is the size of angles you want to "lock" to local angleSize = 45 local function getClosestAngle(ang) --find out how much the new angle is "over" the last 45 degree increment local over = ang % angleSize if over == 0 then --if it's exactly on a 45 deg angle then just return the angle return ang elseif over \> (angleSize / 2) then --if more than halfway from prev 45 deg to next 45 degree then return the next 45 deg angle return ang + (angleSize - over) else --else return the prev 45 deg angle return ang - over end end --test print(getClosestAngle(65)) -- returns 45 print(getClosestAngle(86)) -- returns 90 print(getClosestAngle(211)) -- returns 225 print(getClosestAngle(123)) -- returns 135

Just change the “angleSize” variable to whatever angle sizes you want to snap to, and then feed your current angle into getClosestAngle() to get the angle you should snap to.

local roundingAngle = 45 obj.rotation = math.floor((obj.rotation%360+roundingAngle/2)/roundingAngle)\*roundingAngle

Or you could do that…

thanks for all the help guys! It’s as simple as a rounding function, can’t believe I didn’t think of that.

I’m not sure what you mean but maybe you want to check what the angle of the object is and do something like -

if angle \<= 300 and angle \>= 359 then --object.rotation = 330-- end

–SonicX278 

That could work but it would require checking for every section of the 360 rotation, which seems like a really inefficient way to do it. Is there any other way?

Matters i guess. What/when are you trying to snap into a certain angle?

–SonicX278 

every 45° or 22.5°

So every time object is 45 or 22.5 you wan something to happen?

–SonicX278 

Yes, when the user rotates the object it should stick/ snap to the closest 45° angle. Like this: 0°, 45°, 90°, 135°, 180°, 225°, 270°, 315°, 360°

Ya so your best bet would be go with the way I showed above. That’s how i would do it. It should take no more than 5 min to code the whole thing to working properly. If you have problems doing it i can help no problem!

If someone has a better way i’d be glad to learn something new or refresh my memory!

I just realized that yes there is another way but it will be complicated and will take longer and include doing calculations. Which is really unnecessary.

–SonicX278 

You can work out which 45 degree increment you are closest to, rather than having lots of if statements:

--this is the size of angles you want to "lock" to local angleSize = 45 local function getClosestAngle(ang) --find out how much the new angle is "over" the last 45 degree increment local over = ang % angleSize if over == 0 then --if it's exactly on a 45 deg angle then just return the angle return ang elseif over \> (angleSize / 2) then --if more than halfway from prev 45 deg to next 45 degree then return the next 45 deg angle return ang + (angleSize - over) else --else return the prev 45 deg angle return ang - over end end --test print(getClosestAngle(65)) -- returns 45 print(getClosestAngle(86)) -- returns 90 print(getClosestAngle(211)) -- returns 225 print(getClosestAngle(123)) -- returns 135

Just change the “angleSize” variable to whatever angle sizes you want to snap to, and then feed your current angle into getClosestAngle() to get the angle you should snap to.