vb.netgraphicsgdi+rotatetransform

Use bottom-sx corner as pivot while performing RotateTransform


I know how to rotate a text or a rectangle using the top-sx corner as pivot. For example:

Private Sub Panel1_Click(sender As Object, e As EventArgs) Handles Panel1.Click
    Dim g As Graphics = Panel1.CreateGraphics()
    Dim font As Font = New Font("Arial", 42, FontStyle.Regular, GraphicsUnit.Pixel)
    Dim i As Single
    For i = 0 To 255 Step 30

        Dim myBrush As SolidBrush = New SolidBrush(Color.FromArgb(255, i, 255 - i, i)) 'Green to violet
        'Draw a string and a Rectangle of the same size
        Dim stringSize As SizeF = g.MeasureString("Hello", font)

        g.TranslateTransform(200, 200)
        g.RotateTransform(-i)
        g.DrawString("Hello", font, myBrush, 0, 0)

        g.DrawRectangle(New Pen(Color.FromArgb(50, 255, 0, 0), 1), 0, 0, stringSize.Width, stringSize.Height)
        g.ResetTransform()
        myBrush.Dispose()
    Next
    
    'Draw the center of the rotation
    g.DrawRectangle(Pens.Black, 200 - 5, 200 - 5, 10, 10)
    g.Dispose()
End Sub

With this code I have the following output:

enter image description here

How can I rotate my graphic elements by using the bottom-sx corner as pivot?


Solution

  • Replace as follows:

    Private Sub Panel1_Click(sender As Object, e As EventArgs) Handles Panel1.Click
        Dim g As Graphics = Panel1.CreateGraphics()
        Dim font As Font = New Font("Arial", 42, FontStyle.Regular, GraphicsUnit.Pixel)
        Dim i As Single
        For i = 0 To 255 Step 30
    
            Dim myBrush As SolidBrush = New SolidBrush(Color.FromArgb(255, CInt(i), CInt(255 - i), CInt(i))) 'Green to violet
            'Draw a string and a Rectangle of the same size
            Dim stringSize As SizeF = g.MeasureString("Hello", font)
    
            g.TranslateTransform(200, 200)
            g.RotateTransform(-i)
    
            Dim coorX As Single = 0
            Dim coorY As Single = -stringSize.Height
    
            g.DrawString("Hello", font, myBrush, coorX, coorY)
            g.DrawRectangle(New Pen(Color.FromArgb(50, 255, 0, 0), 1), coorX, coorY, stringSize.Width, stringSize.Height)
    
            g.ResetTransform()
            myBrush.Dispose()
        Next
    
        'Draw the center of the rotation
        g.DrawRectangle(Pens.Black, 200 - 5, 200 - 5, 10, 10)
        g.Dispose()
    End Sub
    

    And here the same version optimized as Memory and Code Friendly:

    Private Sub Panel1_Click(sender As Object, e As EventArgs) Handles Panel1.Click
    
        Using g As Graphics = Panel1.CreateGraphics()
    
            Using font As Font = New Font("Arial", 42, FontStyle.Regular, GraphicsUnit.Pixel)
    
                'Draw a string and a Rectangle of the same size
                Dim stringSize As SizeF = g.MeasureString("Hello", font)
                Dim coorX As Single = 0
                Dim coorY As Single = -stringSize.Height
    
                For i As Integer = 0 To 255 Step 30
                    Using myBrush As SolidBrush = New SolidBrush(Color.FromArgb(255, CInt(i), CInt(255 - i), CInt(i))) 'Green to violet
                        g.TranslateTransform(200, 200)
                        g.RotateTransform(-i)
                        g.DrawString("Hello", font, myBrush, coorX, coorY)
                        g.DrawRectangle(New Pen(Color.FromArgb(50, 255, 0, 0), 1), coorX, coorY, stringSize.Width, stringSize.Height)
                        g.ResetTransform()
                    End Using
                Next
    
            End Using
    
            'Draw the center of the rotation
            g.DrawRectangle(Pens.Black, 200 - 5, 200 - 5, 10, 10)
    
        End Using
    
    End Sub