Friday, July 13, 2012

XNA Tutorial: Smooth Sprite Rotation

Its been a while since my last post. I've bee pretty busy since. You may not have heard but me and my friends have started a games company(Unlucky For Some Studios). So that's been keeping me busy. Any ways a while ago I wrote a tutorial about sprite rotation. Recently I have been experimenting with lerping rotation values so the sprite appears to be rotating smoothly. I have been using the MathHelper.Lerp method to do this. Initially I thought this would work perfectly however I was getting a weird behaviour shown in the following video.
I have a pretty good idea as to what is causing this but explaining it would be kinda hard. I have said may times that I am just crap at Maths and was unable to figure out this problem myself. After a very long google search I managed to find the solution. I thought I would write a blog post about it and hopefully it will make it easier for other people to find and fix.

I used the following code that I found on app hub.
After I used these methods I got the following result which was exactly what I originally set out to do. Instead of calling MathHelper.Lerp you now call CurveAngle and pass in the same parameters.
I hope this helps someone as it helped me. Also give our game a go.

6 comments:

  1. Thank you so much, I've been looking for this for a couple weeks

    ReplyDelete
  2. Dude, ur a genius,
    Thanks a lot
    i was looking for this for a week man.
    And finally i got it

    ReplyDelete
  3. Thanks alot! Really helped, keep it up!

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Hey thanks alot! Really helped me! :)

    I just translated the code into vb.net if somebody needs it:

    Private Function CurveAngle(ByVal _from As Single, ByVal _to As Single, ByVal _step As Single) As Single
    If _step = 0 Then
    Return _from
    End If
    If _from = _to Or _step = 1 Then
    Return _to
    End If

    Dim fromVector As New Vector2(CSng(Math.Cos(_from)), CSng(Math.Sin(_from)))
    Dim toVector As New Vector2(CSng(Math.Cos(_to)), CSng(Math.Sin(_to)))

    Dim currentVector As Vector2 = slerp(fromVector, toVector, _step)

    Return CSng(Math.Atan2(currentVector.Y, currentVector.X))
    End Function

    Private Function slerp(_from As Vector2, _to As Vector2, _step As Single) As Vector2
    If _step = 0 Then
    Return _from
    End If
    If _from = _to Or _step = 1 Then
    Return _to
    End If

    Dim theta As Double = Math.Acos(Vector2.Dot(_from, _to))

    Dim sinTheta As Double = Math.Sin(theta)
    Return CSng((Math.Sin((1 - _step) * theta) / sinTheta)) * _from + CSng((Math.Sin(_step * theta) / sinTheta)) * _to
    End Function

    ReplyDelete