-
Jun 1st, 2010, 07:22 PM
#1
Thread Starter
Stack Overflow moderator
Draw rotated image on Graphics object?
I know that you can pass a Point array to the DrawImage method of the Graphics object to apply rotation, skewing and flipping, but I'm having trouble figuring out how to calculate the rotation. So far I've got:
Code:
Dim radius As Integer = Math.Sqrt((rect.Width / 2) ^ 2 + (rect.Height / 2) ^ 2)
Dim dX As Integer = RadToDeg(Math.Cos(DegToRad(angle))) * radius
Dim dY As Integer = RadToDeg(Math.Tan(DegToRad(angle))) * dX
Dim new_upper_left_corner As New Point(rect.X + (rect.Width \ 2) - dX, rect.Y + (rect.Height \ 2) - dY)
This is all just off the top of my head so far, I'm not sure if it's right. How do I calculate the other points on the rectangle, and is there a built-in VB.NET method that's much easier? (Apart from Graphics.RotateTransform, which is slow and also rotates around 0,0.)
-
Jun 1st, 2010, 07:33 PM
#2
Re: Draw rotated image on Graphics object?
The simple option is to call TranslateTransform first to move the origin to the point you want to rotate about, then call RotateTransform to rotate about that new origin. Here's an example that draws an image spinning in the centre of a form:
Code:
Public Class Form1
Private picture As Image = Image.FromFile(IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.MyPictures, _
"SomeImage.jpg"))
Private angle As Integer = 0
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Me.angle = (Me.angle + 1) Mod 360
Me.Refresh()
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
With e.Graphics
.TranslateTransform(Me.ClientSize.Width \ 2, Me.ClientSize.Height \ 2)
.RotateTransform(Me.angle)
.DrawImage(Me.picture, -Me.picture.Width \ 2, -Me.picture.Height \ 2)
End With
End Sub
End Class
You say that RotateTransform is slow so maybe you don't want to do it like that. I've never done it any other way so I can't tell you how to make it work with a matrix.
-
Jun 2nd, 2010, 06:27 AM
#3
Re: Draw rotated image on Graphics object?
Using a matrix is easy. You apply the operations to the matrix instead of to the Graphics, and then set Graphics.Transform to point at the matrix. What is more, the Matrix class has a handy RotateAt(angle, point) method. The angle is in degrees and there is no need to translate the graphics back and forth. For example:
vb.net Code:
Using mtx As New Drawing2D.Matrix mtx.RotateAt(37.5, New Point(50, 60)) e.Graphics.Transform = mtx End Using e.Graphics.DrawStuff(whatever)
Whether you use a Matrix or operate directly on the Graphics, there is a sneaky pitfall. The operations happen in backwards order (MatrixOrder.Prepend) by default. This is done in order to please mathematicians and to remind programmers that they are of inferior intellect. To make things look more intuitive, you can specify MatrixOrder.Append in most Graphics or Matrix transforms. But that's unnecessary for RotateAt, unless you are sequencing it with other operations such as skewing.
By the way, who says RotateTransform is slow? It uses exactly the same code as Math and is probably better optimized. Anything can be slow if you program it that way.
BB
Last edited by boops boops; Jun 2nd, 2010 at 06:34 AM.
Reason: typo
-
Jun 2nd, 2010, 02:06 PM
#4
Thread Starter
Stack Overflow moderator
Re: Draw rotated image on Graphics object?
Well I compared the performance of TranslateTransform and just adding the coordinates in one of my controls, the XTabControl. TranslateTransform was waaay slower. I want to stay away from xxxTransform methods, and the matrix. Thanks, though!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|