How to transform a shape in VB.NET

无人久伴 提交于 2020-11-29 10:22:25

问题


I'm trying to first draw a shape (which i've done already) and then have it transformed as selected by a user for example, rotated to a certain angle, or scaled, showing this original shape and the newly transformed shape.

I've tried the following on trying to rotate:

Private Sub paint_box_Paint(sender As Object, e As PaintEventArgs) Handles paint_box.Paint
    Dim x As Integer = paint_box.Size.Width / 2
    Dim y As Integer = paint_box.Size.Height / 2

    Dim rect As New Rectangle(x, y, 80, 80)

    ' Create pen.
    Dim blackPen As New Pen(Color.Black, 3)
    ' Create pen.
    Dim redPen As New Pen(Color.Red, 3)
    e.Graphics.DrawRectangle(blackPen, rect)
End Sub

I was expecting to have that shape printed on Form.Load to rotate by the specified angle 30.0F


回答1:


When we want to paint on a Control's surface, we need subscribe to the Paint event of a Control (not all controls provide this event: TextBox controls don't, for example. We could derive a Custom Control class from TextBox and override the OnPaint method. It may be disappointing, though).

To paint and rotate a shape, we need some Fields or Properties to store the references of the objects/values we use for painting. Here, just the Rectangle object that provides the measure of the shape and a single Field to store the rotation angle.

Private drawingRect As Rectangle = New Rectangle(50, 50, 100, 100)
Private rotationAngle As Single = 0.0F

These references allow to change the shape of the object and the rotation angle when needed. When these values change, we just need to call the Invalidate() method of a Control to raise its Paint event.

In Form.Load() (or in the Form's constructor - Public Sub New()) we can define the initial position and size of the shape, if required:

Public Sub New()
    InitializeComponent()
    drawingRect = New Rectangle(50, 50, 100, 100)
End Sub

When we change the measures of a shape, to update the drawing, we call the Control's Invalidate() method. Here, the drawing surface is provided by a GroupBox control.
On a Button.Click(), we update the shape with the new values calling GroupBox.Invalidate(). The drawing will be updated immediately:

Private Sub btnRotate_Click(sender As Object, e As EventArgs) Handles btnRotate.Click
    ' Rotate the shape 45 degrees
    rotationAngle = 45
    GroupBox1.Invalidate()
End Sub

To rotate a shape, we can use two simple methods: the Graphics.RotateTransform method, or the Matrix.RotateAt() method.
I'm using the latter: it's very simple to use, it accepts an angle expressed in degrees and the we just need to provide the coordinates of the rotation.
Here, the shape is rotated using the coordinates of its center point:

Using mx As Matrix = New Matrix
    mx.RotateAt(rotationAngle, New PointF(drawingRect.X + (drawingRect.Width / 2.0F),
                                          drawingRect.Y + (drawingRect.Height / 2.0F)))
    e.Graphics.Transform = mx
    e.Graphics.DrawRectangle(pen, drawingRect)
End Using

Sample of the results:

All the code used to draw and rotate the shape:

Public Class Form1
    Private drawingRect As Rectangle = Rectangle.Empty
    Private rotationAngle As Single = 0.0F

    Public Sub New()
        InitializeComponent()
        drawingRect = New Rectangle(50, 50, 100, 100)
    End Sub

    Private Sub GroupBox1_Paint(sender As Object, e As PaintEventArgs) Handles GroupBox1.Paint
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias
        Using pen As Pen = New Pen(Color.LightGreen, 4),
            mx As Matrix = New Matrix()

            mx.RotateAt(rotationAngle, New PointF(drawingRect.X + (drawingRect.Width / 2.0F),
                                                  drawingRect.Y + (drawingRect.Height / 2.0F)))
            e.Graphics.Transform = mx
            e.Graphics.DrawRectangle(pen, drawingRect)
        End Using
    End Sub

    Private Sub btnPaint_Click(sender As Object, e As EventArgs) Handles btnPaint.Click
        ' Redefine the shape and redraw it
        drawingRect.Location = New Point(100, 100)
        drawingRect.Size = New Size(200, 300)
        GroupBox1.Invalidate()
    End Sub

    Private Sub btnRotate_Click(sender As Object, e As EventArgs) Handles btnRotate.Click
        ' Rotate the shape 45 degrees
        rotationAngle = 45
        GroupBox1.Invalidate()
    End Sub
End Class


来源:https://stackoverflow.com/questions/56073098/how-to-transform-a-shape-in-vb-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!