📄 carc.vb
字号:
'圆弧类
Imports System.Drawing.Drawing2D
Imports System.Math
Public Class CArc
Inherits CGElement
Private m_Center, m_Begin, m_End As PointF
'圆心属性
Public Property Center() As PointF
Get
Return m_Center
End Get
Set(ByVal Value As PointF)
m_Center = Value
End Set
End Property
'圆弧起点属性
Public Property ABegin() As PointF
Get
Return m_Begin
End Get
Set(ByVal Value As PointF)
m_Begin = Value
End Set
End Property
'圆弧终点属性
Public Property AEnd() As PointF
Get
Return m_End
End Get
Set(ByVal Value As PointF)
m_End = Value
End Set
End Property
'圆弧半径属性,只读
Public ReadOnly Property Radius() As Single
Get
Dim r As Single
r = DistPtoP(m_Center, m_Begin)
Return r
End Get
End Property
'圆弧起点的方位角
Public ReadOnly Property AngleBegin() As Single
Get
Dim aAngle As Single
aAngle = GetAngle(m_Center, m_Begin)
Return aAngle
End Get
End Property
'圆弧终点的方位角
Public ReadOnly Property AngleEnd() As Single
Get
Dim aAngle As Single
aAngle = GetAngle(m_Center, m_End)
Return aAngle
End Get
End Property
'无参构造函数
Public Sub New()
Init()
End Sub
'构造函数,用已知的圆心、起点和另一点进行构造
Public Sub New(ByVal pCenter As PointF, ByVal p1 As PointF, ByVal p2 As PointF)
Init()
m_Center = pCenter
m_Begin = p1
Dim r As Single = DistPtoP(m_Center, m_Begin)
Dim angle2 As Single = GetAngle(m_Center, p2)
m_End.X = r * Cos(angle2) + m_Center.X
m_End.Y = r * Sin(angle2) + m_Center.Y
End Sub
'构造函数,用已知的一个圆弧进行构造
Public Sub New(ByVal aArc As CArc)
With aArc
m_Center = .Center
m_Begin = .ABegin
m_End = .AEnd
End With
End Sub
'初始化圆弧
Private Shadows Sub Init()
MyBase.Init()
With m_Center
.X = 0
.Y = 0
End With
m_Begin = m_Center
m_End = m_Center
End Sub
'绘图
Public Overrides Sub Draw(ByVal g As Graphics, ByVal aDrawMode As geDrawMode)
'将控制点的坐标由世界坐标转换为页面坐标
Dim ec As PointF = WorldtoPage(m_Center)
Dim eb As PointF = WorldtoPage(m_Begin)
Dim ee As PointF = WorldtoPage(m_End)
'获得当前绘图环境的句柄
Dim hdc As IntPtr
hdc = g.GetHdc()
'得到圆弧终点的坐标
Dim X As Single = Radius * Cos(AngleEnd) + m_Center.X
Dim Y As Single = Radius * Sin(AngleEnd) + m_Center.Y
Dim pEnd As New PointF(X, Y)
'设置画笔参数
Dim penPara As Integer() = DrawSettings(hdc, aDrawMode)
'创建画笔
Dim aPen As Long = Win32API.CreatePen(penPara(0), penPara(1), penPara(2))
'把画笔选入绘图环境,并返回原来的画笔
Dim oldP As Long = Win32API.SelectObject(hdc, aPen)
'用刚刚创建的画笔绘圆弧
Win32API.Arc(hdc, ec.X - Radius, ec.Y + Radius, _
ec.X + Radius, ec.Y - Radius, eb.X, _
eb.Y, ee.X, ee.Y)
'把原来的画笔选入绘图环境
Win32API.SelectObject(hdc, oldP)
'删除新创建的画笔
Win32API.DeleteObject(aPen)
'释放绘图环境句柄
g.ReleaseHdc(hdc)
End Sub
'计算圆弧的包围矩形
Public Overrides Function GetBox() As CBox
Dim x1, y1, x2, y2 As Single
Dim i As Integer
Dim aBox As New CBox()
With m_Begin
x1 = Min(.X, m_End.X)
y1 = Min(.Y, m_End.Y)
x2 = Max(.X, m_End.X)
y2 = Max(.Y, m_End.Y)
End With
For i = 0 To 3
If (InArc(AngleBegin, AngleEnd, PI / 2 * i)) Then
'如果圆弧与X轴正向相交
If i = 0 Then
x2 = m_Center.X + Radius
'如果圆弧与Y轴正向相交
ElseIf i = 1 Then
y2 = m_Center.Y + Radius
'如果圆弧与X轴负向相交
ElseIf i = 2 Then
x1 = m_Center.X - Radius
'如果圆弧与Y轴负向相交
ElseIf i = 3 Then
y1 = m_Center.Y - Radius
End If
End If
Next i
With aBox
.minX = x1
.minY = y1
.maxX = x2
.maxY = y2
End With
Return aBox
End Function
'判断角度Angle对应的点是否在Angle1至Angle2的圆弧上
Private Function InArc(ByVal Angle1 As Single, ByVal Angle2 As Single, ByVal Angle As Single) As Boolean
'如果起始角小于终止角
If Angle1 < Angle2 Then
'如果方向角在起始角与终止角之间,则返回True,
'否则返回False
If Angle >= Angle1 And Angle <= Angle2 Then
Return True
Else
Return False
End If
'如果起始角小于终止角
Else
'如果方向角大于起始角或小于终止角,则返回True,
'否则返回False
If Angle >= Angle1 Or Angle <= Angle2 Then
Return True
Else
Return False
End If
End If
End Function
'拾取圆弧
Public Overrides Function Pick(ByVal aPos As PointF) As Boolean
Dim angle, dist As Single
'如果拾取点不在包围矩形中,则该圆弧不被拾取
If Not InBox(GetBox(), aPos) Then
Return False
'否则,进一步判断
Else
'计算拾取点与圆心之间的距离
dist = DistPtoP(aPos, m_Center)
'计算拾取点的方位角
angle = GetAngle(m_Center, aPos)
'如果起始角小于终止角
If AngleBegin < AngleEnd Then
'如果拾取点的方位角界于起始角和终止角之间,
'则拾取点到圆心的距离与圆弧的半径接近,
'则圆弧被拾取,否则不被拾取
If (angle >= AngleBegin And angle <= AngleEnd) _
And Abs(Radius - dist) <= PickRadius Then
Return True
Else
Return False
End If
'如果起始角大于终止角
Else
'如果拾取点的方位角大于等于起始角或小于等于终止角
'且拾取点到圆心的距离与圆弧的半径接近,
'则该圆弧被拾取;否则不被拾取
If (angle >= AngleBegin Or angle <= AngleEnd) And _
Abs(Radius - dist) <= PickRadius Then
Return True
Else
Return False
End If
End If
End If
End Function
End Class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -