Vb6 用放射线画圆
我正在使用此算法渲染许多线条控件,以生成如下内容: 结果相当奇怪: 我认为这是由于cos()和sin()函数的舍入造成的,所以我的问题是,是否有一些算法可以用于修复舍入?或者有没有更好的方法来呈现这样的控件 编辑: 正如Hrqls指出的,问题是我使用的是度而不是弧度。。。这是我最后使用的函数:Vb6 用放射线画圆,vb6,drawing,rounding,user-experience,Vb6,Drawing,Rounding,User Experience,我正在使用此算法渲染许多线条控件,以生成如下内容: 结果相当奇怪: 我认为这是由于cos()和sin()函数的舍入造成的,所以我的问题是,是否有一些算法可以用于修复舍入?或者有没有更好的方法来呈现这样的控件 编辑: 正如Hrqls指出的,问题是我使用的是度而不是弧度。。。这是我最后使用的函数: for i = 0 to 23 '' ... '' create 'line' control '' ... line.x1 = (inner_radius*cos(15
for i = 0 to 23
'' ...
'' create 'line' control
'' ...
line.x1 = (inner_radius*cos(15 * i)) + centerx
line.y1 = (inner_radius*sin(15 * i)) + centery
line.x2 = (outer_radius*cos(15 * i)) + centerx
line.y2 = (outer_radius*sin(15 * i)) + centery
next
像这样称呼它
Sub ProgressAnim(ByVal centerx, _
ByVal centery, _
ByVal outer_radius, _
ByVal inner_radius, _
ByVal step_count, _
ByVal line_width)
Dim pi
Dim degstep
Dim scan
Dim newcontrol As Line
Dim controlid
pi = 4 * Atn(1)
degstep = pi / (step_count / 2)
For scan = 0 To step_count - 1
controlid = "line" & (scan + 1)
Set newcontrol = Me.Controls.Add("vb.line", controlid)
newcontrol.X1 = centerx + (inner_radius * Cos(degstep * scan))
newcontrol.Y1 = centery + (inner_radius * Sin(degstep * scan))
newcontrol.X2 = centerx + (outer_radius * Cos(degstep * scan))
newcontrol.Y2 = centery + (outer_radius * Sin(degstep * scan))
newcontrol.BorderStyle = 1
newcontrol.BorderWidth = line_width
newcontrol.Visible = True
Next
End Sub
产生以下结果:
这与我的预期非常接近。。。遗憾的是,我仍然不知道如何实现抗锯齿,但这就可以了。(至少目前是这样):将i=0到23的
更改为i=0到21的
和(15*i)
与(0.3*i)
使用计时器1在form1中尝试该代码:
ProgressAnim 150, 250, 16, 9, 18, 1
检查本例中的数字以查看绘图行为。您的问题是,当VB使用弧度作为角度时,您以度为单位计算角度
请查看以下项目:
Dim c As Integer, centerx As Integer, centery As Integer, inner_radius As Integer, outer_radius As Integer
Dim x1 As Single, y1 As Single, x2 As Single, y2 As Single
Private Sub Form_Load()
c = 0
centerx = Form1.Width / 2
centery = Form1.Height / 2
inner_radius = 1200
outer_radius = 1
Timer1.Interval = 200
End Sub
Private Sub Timer1_Timer()
x1 = (inner_radius * Cos(0.3 * c)) + centerx
y1 = (inner_radius * Sin(0.3 * c)) + centery
x2 = (outer_radius * Cos(0.3 * c)) + centerx
y2 = (outer_radius * Sin(0.3 * c)) + centery
Line (x1, y1)-(x2, y2), RGB(0, 0, 0)
c = c + 1
If c = 21 Then Timer1.Enabled = False
End Sub
选项显式
专用子表单_Click()
牵引轮
端接头
专用副牵引轮()
作为整数的Dim intI
单瓣
单瓣的
Dim sngCenterX为单个,sngCenterY为单个
尺寸sngX1为单个,sngY1为单个
尺寸sngX2为单个,sngY2为单个
单步调暗
单根
将sngCos作为单个,将sngSin作为单个
'计算表单大小
sngRadius=(标度宽度-240)/2
sngRadiusY=(比例高度-240)/2
sngCenterX=120+sngRadius
sngcentry=120+sngRadiusY
如果sngRadiusY
单击表单以绘制控制盘
Atn(1)是PI/4。。。对于24行,需要将2*PI除以24。。所以你需要把π除以12。。。这使得你把Atn(1)除以3,我会通过使用2PI的适当分数来确保你保持最大的精度
摆弄常数,直到大致得到所需:
Option Explicit
Private Sub Form_Click()
DrawWheel
End Sub
Private Sub DrawWheel()
Dim intI As Integer
Dim sngRadius As Single
Dim sngRadiusY As Single
Dim sngCenterX As Single, sngCenterY As Single
Dim sngX1 As Single, sngY1 As Single
Dim sngX2 As Single, sngY2 As Single
Dim sngStep As Single
Dim sngAngle As Single
Dim sngCos As Single, sngSin As Single
'calculate form sizes
sngRadius = (ScaleWidth - 240) / 2
sngRadiusY = (ScaleHeight - 240) / 2
sngCenterX = 120 + sngRadius
sngCenterY = 120 + sngRadiusY
If sngRadiusY < sngRadius Then sngRadius = sngRadiusY
'draw circle
Circle (sngCenterX, sngCenterY), sngRadius
'calculate step between lines
sngStep = Atn(1) / 3
'draw lines
For intI = 0 To 23
'calculate angle for each line
sngAngle = sngStep * intI
'calculate coordinates for each line
sngCos = Cos(sngAngle)
sngSin = Sin(sngAngle)
sngX1 = sngCenterX + sngCos * sngRadius / 10
sngY1 = sngCenterY + sngSin * sngRadius / 10
sngX2 = sngCenterX + sngCos * sngRadius
sngY2 = sngCenterY + sngSin * sngRadius
'draw each lines
Line (sngX1, sngY1)-(sngX2, sngY2)
'print sequence number
Print CStr(intI)
Next intI
End Sub
请发布您的变量声明。。。变量的类型是什么。。。在所有表单代码和模块的顶部使用“option explicit”以确保声明所有变量Swall,变量的类型都是变量,但我完全走错了方向。。。问题是我用的是degs而不是rads。我也走错了路,直到我在行尾打印了数字。。这表明这些线条并没有按照我假设的顺序打印,而是跳过了圆圈的大部分,事实上绕着圆圈转了好几圈。。因此,角度步长太大:)*facepalm*…度而不是弧度。。。我希望VB6智能感知更清晰。。。谢谢
Option Explicit
Private Sub Form_Load()
Timer.Interval = 50
End Sub
Private Sub Timer_Timer()
DrawRadialLines
End Sub
Private Sub DrawRadialLines()
Const ksngPI As Single = 3.14159!
Const ksngCircle As Single = 2! * ksngPI
Const ksngInnerRadius As Single = 130!
Const ksngOuterRadius As Single = 260!
Const ksngCenterX As Single = 1200!
Const ksngCenterY As Single = 1200!
Const klSegmentCount As Long = 12
Const klLineWidth As Long = 3
Static s_lActiveSegment As Integer ' The "selected" segment.
Dim lSegment As Long
Dim sngRadians As Single
Dim sngX1 As Single
Dim sngY1 As Single
Dim sngX2 As Single
Dim sngY2 As Single
Dim cLineColour As OLE_COLOR
Me.DrawWidth = klLineWidth
' Overdraw previous graphic.
Me.Line (ksngCenterX - ksngOuterRadius - Screen.TwipsPerPixelX * 2, ksngCenterY - ksngOuterRadius - Screen.TwipsPerPixelY * 2)-(ksngCenterX + ksngOuterRadius + Screen.TwipsPerPixelX * 2, ksngCenterY + ksngOuterRadius + Screen.TwipsPerPixelY * 2), Me.BackColor, BF
For lSegment = 0 To klSegmentCount - 1
'
' Work out the coordinates for the line to be draw from the outside circle to the inside circle.
'
sngRadians = (ksngCircle * CSng(lSegment)) / klSegmentCount
sngX1 = (ksngOuterRadius * Cos(sngRadians)) + ksngCenterX
sngY1 = (ksngOuterRadius * Sin(sngRadians)) + ksngCenterY
sngX2 = (ksngInnerRadius * Cos(sngRadians)) + ksngCenterX
sngY2 = (ksngInnerRadius * Sin(sngRadians)) + ksngCenterY
' Work out how many segments away from the "current segment" we are.
' The current segment should be the darkest, and the further away from this segment we are, the lighter the colour should be.
Select Case Abs(Abs(s_lActiveSegment - lSegment) - klSegmentCount \ 2)
Case 0!
cLineColour = RGB(0, 0, 255)
Case 1!
cLineColour = RGB(63, 63, 255)
Case 2!
cLineColour = RGB(117, 117, 255)
Case Else
cLineColour = RGB(181, 181, 255)
End Select
Me.Line (sngX1, sngY1)-(sngX2, sngY2), cLineColour
Next lSegment
' Move the current segment on by one.
s_lActiveSegment = (s_lActiveSegment + 1) Mod klSegmentCount
End Sub