Vb6 用放射线画圆

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

我正在使用此算法渲染许多线条控件,以生成如下内容:

结果相当奇怪:

我认为这是由于cos()和sin()函数的舍入造成的,所以我的问题是,是否有一些算法可以用于修复舍入?或者有没有更好的方法来呈现这样的控件

编辑:

正如Hrqls指出的,问题是我使用的是度而不是弧度。。。这是我最后使用的函数:

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