Oct 10, 2007

Rotating an image around its center in .NET

Rotating an image around its center in .NET#

As you can see on the new screenshots for the WeFly247.NET Passenger website, there's a dynamic flightmap image displaying the route the plane has already traveled and where the plane is at now.

As I was replacing some hard-coded info (like the image to use for the map, the start- and endpoints of the flight on the map, ...), I figured I was also going to need to rotate the plane dynamically so that it would follow the path (I wouldn't feel too comfortable if I was looking at a flightmap where my plane seemed to fly sideways). Before that, I had just rotated the stat ic image itself, but if the flight path can change, so can the rotation.

There is an Image.Rotat eFlip method but that only allows rotating over 90/180/270 degrees. I also looked at some mat rix transformations on a Region object using Matrix.Rotate, but that seemed a little too hard to get working. Furthermore, I wanted to rotat e the plane around its center (not around the upper left corner as most rotations do) so I sat down and thought deeply about rot ation equations (so my math teacher was right, it does come in handy sometimes!), decided I forgot all about it (sorry teach), and looked it up again.

After rotating a point (x, y) around the origin over an angle a, the new coordinates (x', y') are:

x' = x cos(a) + y sin(a)
y' = -x sin(a) + y cos(a)

Now you can use a Graphics. DrawImage method overload to draw the image in a given parallelogram extrapolated from an array of three points. That would do just fine to rot ate the image if I could calculate the three points, which I could using the simple formulas above. So my final implementation to draw a rot ated image onto a graphics object became (beware: VB.NET snippet coming up ;-) ):

' Draws an image onto the given graphics object. The image is rot ated by a specified angle
' (in radians) around its center and then drawn at the given center point.
Private Sub DrawImageRot atedAroundCenter(ByVal g As Graphics, _
    ByVal center As Point, ByVal img As Image, ByVal angle As Double)

     ' Think of the image as a rectangle that needs to be drawn rotated.
     ' Rotate the coordinates of the rectangle's corners.
     Dim upperLeft As Point = RotatePoint(New Point(-img.Width / 2, img.Height / 2), angle)
     Dim upperRight As Point = RotatePoint(New Point(img.Width / 2, img.Height / 2), angle)
     Dim lowerLeft As Point = RotatePoint(New Point(-img.Width / 2, -img.Height / 2), angle)

     ' Create the points array by offsetting the coordinates with the center.
     Dim points() As Point = {upperLeft + center, upperRight + center, lowerLeft + center}
    
    ' Draw the rotated image.
    g.DrawImage(img, points)

End Sub

' Rotates a point around the origin by the specified angle (in radians).
' Rotation adheres to the following rules for the new coordin ates:
' x' = x cos(a) + y sin(a)
' y' = -x sin(a) + y cos(a)
Private Function RotatePoint( ByVal p As Point, ByVal angle As Double) As Point

     Dim x As Integer = p.X * Math.Cos(angle) + p.Y * Math. Sin(angle)
    Dim y As Integer = -p.X * Math. Sin(angle) + p.Y * Math.Cos(angle)

     Return New Point(x, y)

End Function

original source: http://jelle.druyts.net/2004/05/26/RotatingAnImageAroundItsCenterInNET.aspx

No comments:

Post a Comment