vb.net - 如何在 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 事件(并非所有控件都提供此事件:例如 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
结果样本:
另请参阅:
使用比率绘制和缩放矩形
如何使用 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
推荐阅读
- android - android P 中的 GCM 推送通知问题 (28)
- php - 以root身份运行的脚本中的PHP邮件返回路径
- c# - 在 Transact-SQL 上:可以构建一个语句来创建一个新列,同时使用来自同一个表的另一列的数据。
- c# - 在 Asp.net 中的 Ajax 调用不成功
- php - 强制扩展具有主体的方法
- python - 使用 matplotlib 或 PIL 将 3d numpy 数组绘制为 3d 图像
- visual-studio - 如何使用 VSCode 在 GOARCH=386 的 64 位 GO 项目中使用 32 位 DLL
- excel - 用外部数据表覆盖单元格
- r - 来自 csv 的 R 中的地理编码 - 40,000 行
- openmdao - BSpline 结合显式和外部代码表现不同