2014-06-06 32 views
2
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 

我使用這個算法,以呈現多線控制,使類似以下內容:繪製與徑向線一圈

enter image description here

結果是相當奇特:

enter image description here

我認爲這是由於cos()和sin()函數的舍入,所以我的問題是,是否有一些算法我可以申請修復舍入?或者有更好的方法來呈現這種控制,也許?

編輯:

的問題,指出通過Hrqls是,我是用度而非弧度......這是我結束了使用功能:

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 

調用它這樣

ProgressAnim 150, 250, 16, 9, 18, 1 

產生這樣的:

enter image description here

這更接近我的預期......可悲的是,我仍然不知道如何實現抗鋸齒,但是這樣做。 (目前,至少):)

+0

請發表您的變量聲明......是什麼類型的變量? ...在所有表單代碼和模塊的頂部使用「顯式選項」以確保您聲明所有變量 – Hrqls

+1

嗯,變量的類型是Variant,但我完全處於錯誤的軌道......問題在於我使用的是degs而不是rads。 – ferc

+0

我在錯誤的軌道上,直到我在行尾打印數字..這告訴我,我以假定的順序打印的線,但跳過大部分的圓,實際上走了圈了幾次..因此角步太大:) – Hrqls

回答

0

你的問題是,你計算角度的度,而VB採用弧度的角度

看看以下項目:

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 

單擊窗體上繪製輪

Atn(1)是PI/4 ...對於24行,您需要將2 * PI除以24 ..因此您需要將PI除以12 ...這使您將Atn(1)除以3

+0

* facepalm * ...度,而不是弧度...我想VB6 intellisense更清晰...謝謝! – ferc

0

變化for i = 0 to 23for i = 0 to 21(15 * i)(0.3 * i)

嘗試在Form1的代碼用定時器1:

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 

檢查你的號碼在這個例子中請參閱繪圖行爲。

0

我會確保通過使用適當的2PI分數保持最高的準確性。

與常量小提琴,直到你大概你想要什麼:

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