最近在给人家做一个画线的小东东,
可是当斜率比较大时画出来的直线由于升得很快显得很粗糙。
我是在 PICTUREBOX 里面画的,pic.ScaleMode = vbTwips
THANKS 。

解决方案 »

  1.   

    '作者:陨落雕(thirdapple)
    'E-Mail:[email protected]
    'website:www.aivisoft.net
    '代码说明:采用二次线性插值的方法实现了光滑直线,鉴于论坛上
    '          很多人都问,就顺便写了这个代码,不过为了方便,直
    '          接用了SetPixel,效率……
    '本代码可以随处引用,但需注明作者、出处Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As LongFunction GetRedValue(Color As Long) As Integer
    GetRedValue = Color And &HFF
    End FunctionFunction GetGreenValue(Color As Long) As Integer
    GetGreenValue = (Color And 65280) \ 256
    End FunctionFunction GetBlueValue(Color As Long) As Integer
    GetBlueValue = (Color And &HFF0000) \ 65536
    End FunctionFunction Min(s1 As Long, s2 As Long) As Long
    If s1 < s2 Then Min = s1 Else Min = s2
    End FunctionFunction Max(s1 As Long, s2 As Long) As Long
    If s1 > s2 Then Max = s1 Else Max = s2
    End FunctionPrivate Sub CmdDraw_Click()
    Dim Scal As Double, Gray As Long, MinX As Long, MaxX As Long, MinY As Long, MaxY As Long
    Dim X1 As Long, X2 As Long, Y1 As Long, Y2 As Long, X3 As Double, Y3 As Double, a As Double, b As Double
    Dim Red As Long, Green As Long, Blue As Long, BackRed As Long, BackGreen As Long, BackBlue As Long
    Dim FrontRed As Long, FrontGreen As Long, FrontBlue As LongBackRed = GetRedValue(Me.BackColor)
    BackGreen = GetGreenValue(Me.BackColor)
    BackBlue = GetBlueValue(Me.BackColor)FrontRed = GetRedValue(Line1.BorderColor)
    FrontGreen = GetGreenValue(Line1.BorderColor)
    FrontBlue = GetBlueValue(Line1.BorderColor)Line1.Visible = False
    MinX = Min(Line1.X1, Line1.X2): MaxX = Max(Line1.X1, Line1.X2)
    MinY = Min(Line1.Y1, Line1.Y2): MaxY = Max(Line1.Y1, Line1.Y2)
    If (Line1.Y1 < Line1.Y2 And Line1.X1 < Line1.X2) Or (Line1.Y1 > Line1.Y2 And Line1.X1 > Line1.X2) Then
      If Abs(Line1.X1 - Line1.X2) > Abs(Line1.Y1 - Line1.Y2) Then
        Scal = Abs(Line1.Y2 - Line1.Y1) / Abs(Line1.X2 - Line1.X1)
        For i = 0 To MaxX - MinX
          Y3 = i * Scal + MinY: Y1 = Int(Y3): Y2 = Y1 + 1
          a = Y2 - Y3: b = Y3 - Y1
          Red = a * BackRed + b * FrontRed
          Green = a * BackGreen + b * FrontGreen
          Blue = a * BackBlue + b * FrontBlue
          SetPixel Me.hdc, i + MinX, Y2, RGB(Red, Green, Blue)
          Red = b * BackRed + a * FrontRed
          Green = b * BackGreen + a * FrontGreen
          Blue = b * BackBlue + a * FrontBlue
          SetPixel Me.hdc, i + MinX, Y1, RGB(Red, Green, Blue)
        Next i
      Else
        Scal = Abs(Line1.X2 - Line1.X1) / Abs(Line1.Y2 - Line1.Y1)
        For i = 0 To MaxY - MinY
          X3 = i * Scal + MinX: X1 = Int(X3): X2 = X1 + 1
          a = X2 - X3: b = X3 - X1
          Red = a * BackRed + b * FrontRed
          Green = a * BackGreen + b * FrontGreen
          Blue = a * BackBlue + b * FrontBlue
          SetPixel Me.hdc, X2, i + MinY, RGB(Red, Green, Blue)
          Red = b * BackRed + a * FrontRed
          Green = b * BackGreen + a * FrontGreen
          Blue = b * BackBlue + a * FrontBlue
          SetPixel Me.hdc, X1, i + MinY, RGB(Red, Green, Blue)
        Next i
      End If
    Else
      If Abs(Line1.X1 - Line1.X2) > Abs(Line1.Y1 - Line1.Y2) Then
        Scal = -Abs(Line1.Y2 - Line1.Y1) / Abs(Line1.X2 - Line1.X1)
        For i = 0 To MaxX - MinX
          Y3 = i * Scal + MaxY: Y1 = Int(Y3): Y2 = Y1 + 1
          a = Y2 - Y3: b = Y3 - Y1
          Red = a * BackRed + b * FrontRed
          Green = a * BackGreen + b * FrontGreen
          Blue = a * BackBlue + b * FrontBlue
          SetPixel Me.hdc, i + MinX, Y2, RGB(Red, Green, Blue)
          Red = b * BackRed + a * FrontRed
          Green = b * BackGreen + a * FrontGreen
          Blue = b * BackBlue + a * FrontBlue
          SetPixel Me.hdc, i + MinX, Y1, RGB(Red, Green, Blue)
        Next i
      Else
        Scal = -Abs(Line1.X2 - Line1.X1) / Abs(Line1.Y2 - Line1.Y1)
        For i = 0 To MaxY - MinY
          X3 = i * Scal + MaxX: X1 = Int(X3): X2 = X1 + 1
          a = X2 - X3: b = X3 - X1
          Red = a * BackRed + b * FrontRed
          Green = a * BackGreen + b * FrontGreen
          Blue = a * BackBlue + b * FrontBlue
          SetPixel Me.hdc, X2, i + MinY, RGB(Red, Green, Blue)
          Red = b * BackRed + a * FrontRed
          Green = b * BackGreen + a * FrontGreen
          Blue = b * BackBlue + a * FrontBlue
          SetPixel Me.hdc, X1, i + MinY, RGB(Red, Green, Blue)
        Next i
      End If
    End If
    Me.Refresh
    End SubPrivate Sub Form_Load()
    Me.ScaleMode = vbPixels
    Me.AutoRedraw = True
    End SubPrivate Sub Form_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    Line1.Visible = True
    Line1.X1 = x: Line1.Y1 = y
    End SubPrivate Sub Form_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = vbLeftButton Then Line1.X2 = x: Line1.Y2 = y
    End SubPrivate Sub Form_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    Line1.X2 = x: Line1.Y2 = y
    End Sub
      

  2.   

    首先说明一下,画线效率最高的是BRESENHAM算法,而不是上面使用的斜率计算,至于为了美观想消除锯齿可以进行插值,也可以使用边缘模糊技术。但由于显示器分辨率有限,想绝对光滑是不可能的。