3/11/08

PointAt v2.0

In Tutorial 6 (The PointAt method), I suggested a way one sprite can "point" at another, given totally arbitrary tree nesting / matrix transform between the two objects. The code was:

 ''' <summary>
 ''' Point one sprite's origin at another sprite's origin
 ''' </summary>
 Public Sub PointAt(ByVal thePointer As Sprite, ByVal theTarget As Sprite)

 Dim objTargetWorldPosition As Vector2

 If theTarget.Parent IsNot Nothing Then
 objTargetWorldPosition = Vector2.Transform(theTarget.Location, theTarget.Parent.DrawMatrix)
 Else
 objTargetWorldPosition = theTarget.Location
 End If

 thePointer.Rotation = 0

 With Vector2.Transform(objTargetWorldPosition, Matrix.Invert(thePointer.DrawMatrix)) - thePointer.Origin

 thePointer.Rotation = CSng(Math.Atan2(.Y, .X) + (Math.PI / 2))

 End With

 End Sub

And that works, but I realized an alternative way to solve the same problem today. I haven't compared the raw performance of this new way vs. the other, so I can't say if it's faster... but I suspect it might be.

 ''' <summary>
 ''' Gets the radian between two sprite origins
 ''' </summary>
 Public Function PointAt(ByVal thePointer As Sprite, ByVal theTarget As Sprite) As Single

 Dim a, b, c As Vector2

 Vector2.Transform(thePointer.Origin, thePointer.DrawMatrix, a)
 Vector2.Transform(theTarget.Origin, theTarget.DrawMatrix, b)

 c = b - a

 Return CSng(Math.Atan2(c.Y, c.X) + MathHelper.PiOver2)

 End Function

I made it a function that returns the radian value, so that you can do with it whatever you so choose - either assign it to the Rotation value of thePointer, or just query the angle between two things for whatever reason.

0 comments: