如何在 VB.NET 中变换形状

How to transform a shape in VB.NET

我正在尝试先绘制一个形状(我已经完成了),然后根据用户的选择对其进行转换,例如,旋转到某个角度或缩放,以显示原始形状和新变形的形状。

我在尝试旋转时尝试了以下方法:

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

我希望在 Form.Load 上打印那个形状以旋转指定的角度 30.0F

当我们想在控件的表面上绘画时,我们需要订阅控件的 Paint event(并非所有控件都提供此事件:例如,TextBox 控件不提供。我们可以派生一个自定义从 TextBox 控制 class 并重写 OnPaint 方法。虽然这可能会令人失望)。

要绘制和旋转形状,我们需要一些字段或属性来存储我们用于绘制的 objects/values 的引用。在这里,只有 Rectangle 提供形状度量的对象和一个 single 存储旋转角度的字段。

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

这些引用允许在需要时更改对象的形状和旋转角度。当这些值改变时,我们只需要调用控件的 Invalidate() 方法来引发它的 Paint 事件。

Form.Load()(或在窗体的构造函数中-Public Sub New())我们可以定义形状的初始位置和大小,如果需要的话:

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

当我们改变形状的尺寸时,为了更新绘图,我们调用控件的Invalidate()方法。此处,绘图表面由 GroupBox 控件提供。
Button.Click() 上,我们使用调用 GroupBox.Invalidate() 的新值更新形状。图纸马上更新:

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

要旋转形状,我们可以使用两种简单的方法:Graphics.RotateTransform method, or the Matrix.RotateAt() 方法。
我正在使用后者:它使用起来非常简单,它接受以度数表示的角度,我们只需要提供旋转的坐标。
这里,形状使用其中心点的坐标旋转:

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

结果示例:

另请参阅:

用于绘制和旋转形状的所有代码:

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