Where I talk about game development and other tech stuff.
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.
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
Thank you so much, I've been looking for this for a couple weeks
ReplyDeleteGlad I could help.
DeleteDude, ur a genius,
ReplyDeleteThanks a lot
i was looking for this for a week man.
And finally i got it
Thanks alot! Really helped, keep it up!
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHey thanks alot! Really helped me! :)
ReplyDeleteI 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