首页 > 解决方案 > 如何在 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

标签: vb.netwinformsmatrixgraphicsrotatetransform

解决方案


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

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

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

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

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

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

当我们改变一个形状的尺寸,更新绘图,我们调用控件的Invalidate()方法。在这里,绘图表面由 GroupBox 控件提供。
在 a 上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方法或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

结果样本:

Graphis DrawRectangle Matrix RotateAt

另请参阅:
使用比率绘制和缩放矩形
如何使用 Paint 事件在鼠标坐标处绘制形状

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

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

推荐阅读