Rotating the wrong way

I’m having a problem when I rotate an object using  transition.to( player, { rotation =  rotationangle, time=400, transition=continuousLoop  } )

I’m using the standard :   local angleInDegrees = (math.deg(math.atan2( (y2-y1), (x2-x1))))

My player will rotate the long way round the circle instead of rotating using the shortest rotation path.

Is this a corona problem or am I missing something?

On object:rotate(delta), a positive number rotates the object clockwise and a negative number rotates the object counter-clockwise.

So if the same logic applies to transitions, I suppose if the rotation is greater than it was before the transition, it will rotate clockwise, and if it’s smaller, it will rotate counter-clockwise.

Here is a picture to describe the problem:

I want to rotate from one blue point to the other.

The green arrow is the rotation I want to follow.

The red is the rotation that actually happens.

Thanks, Greg

Yep, I understand the problem. The angle you’re specifying in “rotationangle” must be smaller than the angle the object had before the transition. Here’s some example code:

local r = display.newRect(200, 200, 100, 100) transition.to(r, {time = 3000, rotation = 500, onComplete=function()     transition.to(r, {time = 3000, rotation = 200}) end})

This rotates the rectangle 500 degrees clockwise, then 300 degrees counter-clockwise.

This is my rotate function:

function getImageRotationPlayer(x1,y1,x2,y2)

    if x1 ~=nil and y1 ~=nil and x2~=nil and y2~=nil then
        local angleInDegrees = (math.deg(math.atan2( (y2-y1), (x2-x1))))
        return angleInDegrees
    else
        return 0
    end
    
end

I then rotate and move:(px and py are touch locations)

local rotationangle =getImageRotationPlayer(player.x, player.y, px,py)

transition.to( player, { rotation =  rotationangle, time=400, transition=continuousLoop  } )

mte.moveSpriteTo({sprite = player, levelPosX = px, levelPosY = py, time = 1500, transition = easing.inOutSine, onComplete = mte.setCameraFocus(player), })

** The thing is that the angle is correct,the quirkyness is that it moves the longer way to get there!

I tried to calculate distance and rotation direction but no go!

     local endangle =getImageRotationPlayer(player.x, player.y, px,py)
        local startangle = player.rotation
        print ("PLAYER ANGLE : "… tostring(player.rotation))
        print ("ROTATION ANGLE : "… tostring(endangle))

        local direction = (startangle < endangle) and 1 or -1
        local distance = math.abs(endangle - startangle)
        print ("DISTANCE : "… tostring(distance))
        local step_direction
        if distance < 180 then
            step_direction = direction
        else
            step_direction = -direction
        end
         trotation = distance * step_direction
         transition.to( player, { rotation = trotation, time=400, transition=easing.linear  } )
  

hi @gb8,

Have you look into @horacebury’s indispensable mathlib.lua?

https://gist.github.com/HoraceBury/9431861

I remember using his library years before for rotation of some kind.

You may try using angleOf and rotateTo functions.

Sorry i could not find the code i used before.

Good Luck!

burhan

burhan, you just saved me!!! Horace had it coverd using this function after calculating the angle:

function smallestAngleDiff( target, source )
    local a = target - source
    if (a > 180) then
        a = a - 360
    elseif (a < -180) then
        a = a + 360
    end
    return a
end
 

Seems so simple now!!!  Many thanks, Greg

On object:rotate(delta), a positive number rotates the object clockwise and a negative number rotates the object counter-clockwise.

So if the same logic applies to transitions, I suppose if the rotation is greater than it was before the transition, it will rotate clockwise, and if it’s smaller, it will rotate counter-clockwise.

Here is a picture to describe the problem:

I want to rotate from one blue point to the other.

The green arrow is the rotation I want to follow.

The red is the rotation that actually happens.

Thanks, Greg

Yep, I understand the problem. The angle you’re specifying in “rotationangle” must be smaller than the angle the object had before the transition. Here’s some example code:

local r = display.newRect(200, 200, 100, 100) transition.to(r, {time = 3000, rotation = 500, onComplete=function() &nbsp;&nbsp; &nbsp;transition.to(r, {time = 3000, rotation = 200}) end})

This rotates the rectangle 500 degrees clockwise, then 300 degrees counter-clockwise.

This is my rotate function:

function getImageRotationPlayer(x1,y1,x2,y2)

    if x1 ~=nil and y1 ~=nil and x2~=nil and y2~=nil then
        local angleInDegrees = (math.deg(math.atan2( (y2-y1), (x2-x1))))
        return angleInDegrees
    else
        return 0
    end
    
end

I then rotate and move:(px and py are touch locations)

local rotationangle =getImageRotationPlayer(player.x, player.y, px,py)

transition.to( player, { rotation =  rotationangle, time=400, transition=continuousLoop  } )

mte.moveSpriteTo({sprite = player, levelPosX = px, levelPosY = py, time = 1500, transition = easing.inOutSine, onComplete = mte.setCameraFocus(player), })

** The thing is that the angle is correct,the quirkyness is that it moves the longer way to get there!

I tried to calculate distance and rotation direction but no go!

     local endangle =getImageRotationPlayer(player.x, player.y, px,py)
        local startangle = player.rotation
        print ("PLAYER ANGLE : "… tostring(player.rotation))
        print ("ROTATION ANGLE : "… tostring(endangle))

        local direction = (startangle < endangle) and 1 or -1
        local distance = math.abs(endangle - startangle)
        print ("DISTANCE : "… tostring(distance))
        local step_direction
        if distance < 180 then
            step_direction = direction
        else
            step_direction = -direction
        end
         trotation = distance * step_direction
         transition.to( player, { rotation = trotation, time=400, transition=easing.linear  } )
  

hi @gb8,

Have you look into @horacebury’s indispensable mathlib.lua?

https://gist.github.com/HoraceBury/9431861

I remember using his library years before for rotation of some kind.

You may try using angleOf and rotateTo functions.

Sorry i could not find the code i used before.

Good Luck!

burhan

burhan, you just saved me!!! Horace had it coverd using this function after calculating the angle:

function smallestAngleDiff( target, source )
    local a = target - source
    if (a > 180) then
        a = a - 360
    elseif (a < -180) then
        a = a + 360
    end
    return a
end
 

Seems so simple now!!!  Many thanks, Greg

Hi gb8,

I got the same problem here and I understand all the logic behind this equation:

function smallestAngleDiff( target, source )
    local a = target - source
    if (a > 180) then
        a = a - 360
    elseif (a < -180) then
        a = a + 360
    end
    return a
end

The thing I don’t understand is how to callback the last angle (source)  I had the move before…

Hi gb8,

I have the same problem here and I understand all the logic behind this:

function smallestAngleDiff( target, source )
    local a = target - source
    if (a > 180) then
        a = a - 360
    elseif (a < -180) then
        a = a + 360
    end
    return a
end

My problem is that i don’t know how to callback the last angle (source) I had the move before…

Hi leo,

– First get the angle between the two points

  local rotationangle =getImageRotation(player.x, player.y, px,py)

– Figure out which way to turn

local angle = smallestAngleDiff( player.rotation, rotationangle)

– do the turn

transition.to( player, { rotation = player.rotation- angle, time=400, transition=easing.linear  } )

function getImageRotation(x1,y1,x2,y2)
    if x1 ~=nil and y1 ~=nil and x2~=nil and y2~=nil then
        local angleInDegrees = (math.deg(math.atan2( (y2-y1), (x2-x1))))
        return angleInDegrees
    else
        return 0
    end
end

Hope that helps, Greg

I got it, it goes like a charm! I had the wrong approach…

I added this to my code to make it works every additional move:

if (player.rotation > 180) 

player.rotation = player.rotation -360

elseif (player.rotation < -180) then

player.rotation = player.rotation - 360

end

Thank you very much Greg!

If you horizontally flip it (set xScale negative) won’t it rotate the other way round ?