将书写方向保持在圆圈内
Hold the writing direction inside the circle
我画的线在圆圈内写有一个圆圈数字 90。
现在我的问题是数字 90 随着圆的旋转而旋转,例如变成 09!
如何保持书写方向不变?比如,总是情绪低落。
我希望能够像这样移动绘制的线:
我的代码是:
Imports System.Drawing.Drawing2D
Public Class Form1
Private Segments As List(Of Segment) = New List(Of Segment)()
Private NewSegment As Segment = Nothing
Dim P As Pen = New Pen(Color.Black, 1.5)
Dim CIRCLE, ELLIPSE As GraphicsPath
Dim radius = 15
Dim drawFontF As FontFamily = New FontFamily("times new roman")
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
Dim drawString = "90"
CIRCLE = New GraphicsPath()
CIRCLE.AddEllipse(-15, 0, radius * 2, radius * 2)
'****************************
Dim angle = Math.Atan2(20 - e.Location.Y, 5 - e.Location.X)
Dim x3 = 5 + Math.Cos(angle) * radius
Dim y3 = 20 + Math.Sin(angle) * radius
CIRCLE.AddString(drawString, drawFontF, FontStyle.Regular, 10, New Point(x3, y3), Nothing)
P.CustomEndCap = New CustomLineCap(Nothing, CIRCLE)
NewSegment = New Segment(P, e.Location, e.Location, "CIRCLE")
PictureBox1.Refresh()
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If NewSegment Is Nothing Then Return
NewSegment.pt2 = e.Location
PictureBox1.Refresh()
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
Dim PP As Pen = New Pen(Color.Black, 1.5)
PP.CustomEndCap = New CustomLineCap(Nothing, CIRCLE)
Dim H = "CIRCLE"
NewSegment.pen1 = PP
NewSegment.END_CAPS = H
Segments.Add(NewSegment)
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
For Each segment As Segment In Segments
segment.Draw(e.Graphics, Nothing, Nothing)
Next
If NewSegment IsNot Nothing Then
NewSegment.Draw(e.Graphics, Nothing, Nothing)
End If
End Sub
End Class
Class Segment
Public pen1 As Pen
Public pt1, pt2 As Point
Public END_CAPS As String
Public Sub New(pen As Pen, point1 As Point, point2 As Point, END_CAP As String)
pen1 = pen
pt1 = point1
pt2 = point2
END_CAPS = END_CAP
End Sub
Public Sub Draw(gr As Graphics, R As Rectangle, INDEX As Integer)
'*********************
gr.SmoothingMode = SmoothingMode.AntiAlias
gr.DrawLine(pen1, pt1, pt2)
End Sub
End Class
就个人而言,我只是自己手动绘制“端盖”。
此外,我会以完全不同的方式绘制线段:
- 将原点移动到起点
- 围绕新的表面旋转表面
origin 所以 x-axis 指向终点
- 仅使用平移和旋转后将线段绘制为一条线
x-axis
此设置使我们可以更轻松地绘制圆和 90:
- 将原点向外移动一点,沿着仍然旋转的
x-axis,到圆心
- 在原点画圆。
- 将原点向外移动一点,在
圆和圆的边缘。
- 绕原点旋转,这样 90 就会“直立”。
- 画90。
在我们执行步骤 1-8 之前,我们保存图形的当前状态,这样我们就可以在绘制每个线段后“重置”并为下一个线段重复该过程。
样本运行:
示例代码:
Public Class Form1
Private NewSegment As Segment
Private Segments As New List(Of Segment)
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
NewSegment = New Segment(e.Location, e.Location)
Segments.Add(NewSegment)
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If NewSegment Is Nothing Then Return
NewSegment.Point2 = e.Location
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
For Each segment As Segment In Segments
segment.Draw(e.Graphics)
Next
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
NewSegment = Nothing
End Sub
Private Sub PictureBox1_SizeChanged(sender As Object, e As EventArgs) Handles PictureBox1.SizeChanged
PictureBox1.Invalidate()
End Sub
End Class
Class Segment
Private pt1, pt2 As Point
Private angle As Double = 0
Private length As Double = 0
Private Shared SF As StringFormat
Private Const RADIUS As Integer = 20
Private Shared drawString As String = "90"
Private Shared pen1 As New Pen(Color.Black, 1.5)
Private Shared drawFontF As New Font("times new roman", 10)
Private Shared rc As New Rectangle(New Point(-RADIUS, -RADIUS), New Size(RADIUS * 2, RADIUS * 2))
Public Sub New(startPoint As Point, endPoint As Point)
Point1 = startPoint
Point2 = endPoint
End Sub
Public Property Point1 As Point
Get
Return pt1
End Get
Set(value As Point)
pt1 = value
UpdateAngleAndLength()
End Set
End Property
Public Property Point2 As Point
Get
Return pt2
End Get
Set(value As Point)
pt2 = value
UpdateAngleAndLength()
End Set
End Property
Private Sub UpdateAngleAndLength()
angle = Math.Atan2(Point2.Y - Point1.Y, Point2.X - Point1.X) * 180.0 / Math.PI
length = Math.Sqrt(Math.Pow(Point2.X - Point1.X, 2) + Math.Pow(Point2.Y - Point1.Y, 2))
End Sub
Public Sub Draw(gr As Graphics)
If IsNothing(SF) Then
SF = New StringFormat()
SF.Alignment = StringAlignment.Center
SF.LineAlignment = StringAlignment.Center
End If
' save the current state of the graphics
Dim curState As GraphicsState = gr.Save()
' move the origin to the start point of the line
gr.TranslateTransform(Point1.X, Point1.Y)
' rotate the whole surface
gr.RotateTransform(angle)
' draw the line on the x-axis
gr.DrawLine(pen1, 0, 0, CInt(length), 0)
' move the origin along the x-axis to where the center of the circle should be
gr.TranslateTransform(length + RADIUS, 0)
' draw the circle
gr.DrawEllipse(pen1, rc)
' draw the 90 at the opposite end of the circle,
' at 3/4ths of the way to the opposite side,
' but still oriented downwards like "normal"
gr.TranslateTransform(RADIUS / 2.0, 0) ' midway between center and opposite side of circle
' orient back to the "normal" so the 90 is upright
gr.RotateTransform(-angle)
' draw the 90
gr.DrawString(drawString, drawFontF, Brushes.Black, rc, SF)
' put the graphics back to the way it was originally
gr.Restore(curState)
End Sub
End Class
我画的线在圆圈内写有一个圆圈数字 90。 现在我的问题是数字 90 随着圆的旋转而旋转,例如变成 09! 如何保持书写方向不变?比如,总是情绪低落。
我希望能够像这样移动绘制的线:
我的代码是:
Imports System.Drawing.Drawing2D
Public Class Form1
Private Segments As List(Of Segment) = New List(Of Segment)()
Private NewSegment As Segment = Nothing
Dim P As Pen = New Pen(Color.Black, 1.5)
Dim CIRCLE, ELLIPSE As GraphicsPath
Dim radius = 15
Dim drawFontF As FontFamily = New FontFamily("times new roman")
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
Dim drawString = "90"
CIRCLE = New GraphicsPath()
CIRCLE.AddEllipse(-15, 0, radius * 2, radius * 2)
'****************************
Dim angle = Math.Atan2(20 - e.Location.Y, 5 - e.Location.X)
Dim x3 = 5 + Math.Cos(angle) * radius
Dim y3 = 20 + Math.Sin(angle) * radius
CIRCLE.AddString(drawString, drawFontF, FontStyle.Regular, 10, New Point(x3, y3), Nothing)
P.CustomEndCap = New CustomLineCap(Nothing, CIRCLE)
NewSegment = New Segment(P, e.Location, e.Location, "CIRCLE")
PictureBox1.Refresh()
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If NewSegment Is Nothing Then Return
NewSegment.pt2 = e.Location
PictureBox1.Refresh()
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
Dim PP As Pen = New Pen(Color.Black, 1.5)
PP.CustomEndCap = New CustomLineCap(Nothing, CIRCLE)
Dim H = "CIRCLE"
NewSegment.pen1 = PP
NewSegment.END_CAPS = H
Segments.Add(NewSegment)
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
For Each segment As Segment In Segments
segment.Draw(e.Graphics, Nothing, Nothing)
Next
If NewSegment IsNot Nothing Then
NewSegment.Draw(e.Graphics, Nothing, Nothing)
End If
End Sub
End Class
Class Segment
Public pen1 As Pen
Public pt1, pt2 As Point
Public END_CAPS As String
Public Sub New(pen As Pen, point1 As Point, point2 As Point, END_CAP As String)
pen1 = pen
pt1 = point1
pt2 = point2
END_CAPS = END_CAP
End Sub
Public Sub Draw(gr As Graphics, R As Rectangle, INDEX As Integer)
'*********************
gr.SmoothingMode = SmoothingMode.AntiAlias
gr.DrawLine(pen1, pt1, pt2)
End Sub
End Class
就个人而言,我只是自己手动绘制“端盖”。
此外,我会以完全不同的方式绘制线段:
- 将原点移动到起点
- 围绕新的表面旋转表面 origin 所以 x-axis 指向终点
- 仅使用平移和旋转后将线段绘制为一条线 x-axis
此设置使我们可以更轻松地绘制圆和 90:
- 将原点向外移动一点,沿着仍然旋转的 x-axis,到圆心
- 在原点画圆。
- 将原点向外移动一点,在 圆和圆的边缘。
- 绕原点旋转,这样 90 就会“直立”。
- 画90。
在我们执行步骤 1-8 之前,我们保存图形的当前状态,这样我们就可以在绘制每个线段后“重置”并为下一个线段重复该过程。
样本运行:
示例代码:
Public Class Form1
Private NewSegment As Segment
Private Segments As New List(Of Segment)
Private Sub PictureBox1_MouseDown(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseDown
NewSegment = New Segment(e.Location, e.Location)
Segments.Add(NewSegment)
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
If NewSegment Is Nothing Then Return
NewSegment.Point2 = e.Location
PictureBox1.Invalidate()
End Sub
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
For Each segment As Segment In Segments
segment.Draw(e.Graphics)
Next
End Sub
Private Sub PictureBox1_MouseUp(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseUp
NewSegment = Nothing
End Sub
Private Sub PictureBox1_SizeChanged(sender As Object, e As EventArgs) Handles PictureBox1.SizeChanged
PictureBox1.Invalidate()
End Sub
End Class
Class Segment
Private pt1, pt2 As Point
Private angle As Double = 0
Private length As Double = 0
Private Shared SF As StringFormat
Private Const RADIUS As Integer = 20
Private Shared drawString As String = "90"
Private Shared pen1 As New Pen(Color.Black, 1.5)
Private Shared drawFontF As New Font("times new roman", 10)
Private Shared rc As New Rectangle(New Point(-RADIUS, -RADIUS), New Size(RADIUS * 2, RADIUS * 2))
Public Sub New(startPoint As Point, endPoint As Point)
Point1 = startPoint
Point2 = endPoint
End Sub
Public Property Point1 As Point
Get
Return pt1
End Get
Set(value As Point)
pt1 = value
UpdateAngleAndLength()
End Set
End Property
Public Property Point2 As Point
Get
Return pt2
End Get
Set(value As Point)
pt2 = value
UpdateAngleAndLength()
End Set
End Property
Private Sub UpdateAngleAndLength()
angle = Math.Atan2(Point2.Y - Point1.Y, Point2.X - Point1.X) * 180.0 / Math.PI
length = Math.Sqrt(Math.Pow(Point2.X - Point1.X, 2) + Math.Pow(Point2.Y - Point1.Y, 2))
End Sub
Public Sub Draw(gr As Graphics)
If IsNothing(SF) Then
SF = New StringFormat()
SF.Alignment = StringAlignment.Center
SF.LineAlignment = StringAlignment.Center
End If
' save the current state of the graphics
Dim curState As GraphicsState = gr.Save()
' move the origin to the start point of the line
gr.TranslateTransform(Point1.X, Point1.Y)
' rotate the whole surface
gr.RotateTransform(angle)
' draw the line on the x-axis
gr.DrawLine(pen1, 0, 0, CInt(length), 0)
' move the origin along the x-axis to where the center of the circle should be
gr.TranslateTransform(length + RADIUS, 0)
' draw the circle
gr.DrawEllipse(pen1, rc)
' draw the 90 at the opposite end of the circle,
' at 3/4ths of the way to the opposite side,
' but still oriented downwards like "normal"
gr.TranslateTransform(RADIUS / 2.0, 0) ' midway between center and opposite side of circle
' orient back to the "normal" so the 90 is upright
gr.RotateTransform(-angle)
' draw the 90
gr.DrawString(drawString, drawFontF, Brushes.Black, rc, SF)
' put the graphics back to the way it was originally
gr.Restore(curState)
End Sub
End Class