求一段绘制平滑直线的代码。(PS_JOIN_ROUND是否就是绘制平滑直线,还是要定义Pattern?)

解决方案 »

  1.   

    使用双线性插值的方法可以使得绘制的直线相对光滑一些,简单原理说明的代码如下: 
    For i = 0 To MaxX - MinX 
      Y3 = i * Scal + MinY: Y1 = Int(Y3): Y2 = Y1 + 1 
      Gray = (Y2 - Y3) * 255 
      SetPixel Me.hdc, i + MinX, Y2, RGB(Gray, Gray, Gray) 
      Gray = (Y3 - Y1) * 255 
      SetPixel Me.hdc, i + MinX, Y1, RGB(Gray, Gray, Gray) 
    Next i 
    全部代码下载在: 
    http://www.aivisoft.net/Source/SmoothLine.zip 
      

  2.   

    问题解决了,用双线性插值的方法效率还是很高的。这个是绘制宽度为1的平滑直线代码:
    Private Declare Function SetPixel Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long
    Private Declare Function GetPixel Lib "gdi32" (ByVal hDC As Long, ByVal x As Long, ByVal y As Long) As LongPrivate Function Min(a As Long, b As Long) As Long
        If a > b Then
            Min = b
        Else
            Min = a
        End If
    End Function
    Private Function Max(a As Long, b As Long) As Long
        If a > b Then
            Max = a
        Else
            Max = b
        End If
    End Function
    Private Sub SetColor(Red As Long, Green As Long, Blue As Long, crColor As Long)
        Red = crColor And &HFF
        Green = (crColor - Red) / 256 Mod 256
        Blue = crColor And &HFF0000 / 65536
    End SubPrivate Sub DrawSmoothLine(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long, hDC As Long, crColor As Long)
        Dim Scal As Single, MinX As Long, MaxX As Long, MinY As Long, MaxY As Long
        Dim X3 As Single, Y3 As Single
        
        Dim Red As Long, Green As Long, Blue As Long 'Input Color
        SetColor Red, Green, Blue, crColor
        
        Dim bRed As Long, bGreen As Long, bBlue As Long 'Background Color
        Dim tRed As Long, tGreen As Long, tBlue As Long 'Output Color
        Dim Alpha As Single
        
        DoEvents
        
        MinX = Min(X1, X2):         MaxX = Max(X1, X2)
        MinY = Min(Y1, Y2):         MaxY = Max(Y1, Y2)
        
        If (Y1 < Y2 And X1 < X2) Or (Y1 > Y2 And X1 > X2) Then
            If Abs(X1 - X2) > Abs(Y1 - Y2) Then
                Scal = Abs(Y2 - Y1) / Abs(X2 - X1)
                For i = 0 To MaxX - MinX
                    Y3 = i * Scal + MinY:               Y1 = Int(Y3):       Y2 = Y1 + 1
                    
                    Alpha = Y2 - Y3
                    SetColor bRed, bGreen, bBlue, GetPixel(hDC, i + MinX, Y2)
                    
                    tRed = (1 - Alpha) * Red + Alpha * bRed
                    tGreen = (1 - Alpha) * Green + Alpha * bGreen
                    tBlue = (1 - Alpha) * Blue + Alpha * bBlue
                    SetPixel hDC, i + MinX, Y2, RGB(tRed, tGreen, tBlue)
                    
                    Alpha = Y3 - Y1
                    SetColor bRed, bGreen, bBlue, GetPixel(hDC, i + MinX, Y1)
                    
                    tRed = (1 - Alpha) * Red + Alpha * bRed
                    tGreen = (1 - Alpha) * Green + Alpha * bGreen
                    tBlue = (1 - Alpha) * Blue + Alpha * bBlue
                    SetPixel hDC, i + MinX, Y1, RGB(tRed, tGreen, tBlue)
                Next i
            Else
                Scal = Abs(X2 - X1) / Abs(Y2 - Y1)
                For i = 0 To MaxY - MinY
                    X3 = i * Scal + MinX:               X1 = Int(X3):       X2 = X1 + 1
                    
                    Alpha = X2 - X3
                    SetColor bRed, bGreen, bBlue, GetPixel(hDC, X2, i + MinY)
                    
                    tRed = (1 - Alpha) * Red + Alpha * bRed
                    tGreen = (1 - Alpha) * Green + Alpha * bGreen
                    tBlue = (1 - Alpha) * Blue + Alpha * bBlue
                    SetPixel hDC, X2, i + MinY, RGB(tRed, tGreen, tBlue)
                    
                    Alpha = X3 - X1
                    SetColor bRed, bGreen, bBlue, GetPixel(hDC, X1, i + MinY)
                    
                    tRed = (1 - Alpha) * Red + Alpha * bRed
                    tGreen = (1 - Alpha) * Green + Alpha * bGreen
                    tBlue = (1 - Alpha) * Blue + Alpha * bBlue
                    SetPixel hDC, X1, i + MinY, RGB(tRed, tGreen, tBlue)
                Next i
            End If
        Else
            If Abs(X1 - X2) > Abs(Y1 - Y2) Then
                Scal = -Abs(Y2 - Y1) / Abs(X2 - X1)
                For i = 0 To MaxX - MinX
                    Y3 = i * Scal + MaxY:               Y1 = Int(Y3):       Y2 = Y1 + 1
                    
                    Alpha = Y2 - Y3
                    SetColor bRed, bGreen, bBlue, GetPixel(hDC, i + MinX, Y2)
                    
                    tRed = (1 - Alpha) * Red + Alpha * bRed
                    tGreen = (1 - Alpha) * Green + Alpha * bGreen
                    tBlue = (1 - Alpha) * Blue + Alpha * bBlue
                    SetPixel hDC, i + MinX, Y2, RGB(tRed, tGreen, tBlue)
                    
                    Alpha = Y3 - Y1
                    SetColor bRed, bGreen, bBlue, GetPixel(hDC, i + MinX, Y1)
                    
                    tRed = (1 - Alpha) * Red + Alpha * bRed
                    tGreen = (1 - Alpha) * Green + Alpha * bGreen
                    tBlue = (1 - Alpha) * Blue + Alpha * bBlue
                    SetPixel hDC, i + MinX, Y1, RGB(tRed, tGreen, tBlue)
                Next i
            Else
                Scal = -Abs(X2 - X1) / Abs(Y2 - Y1)
                For i = 0 To MaxY - MinY
                    X3 = i * Scal + MaxX:               X1 = Int(X3):       X2 = X1 + 1
                    
                    Alpha = X2 - X3
                    SetColor bRed, bGreen, bBlue, GetPixel(hDC, X2, i + MinY)
                    
                    tRed = (1 - Alpha) * Red + Alpha * bRed
                    tGreen = (1 - Alpha) * Green + Alpha * bGreen
                    tBlue = (1 - Alpha) * Blue + Alpha * bBlue
                    SetPixel hDC, X2, i + MinY, RGB(tRed, tGreen, tBlue)
                    
                    Alpha = X3 - X1
                    SetColor bRed, bGreen, bBlue, GetPixel(hDC, X1, i + MinY)
                    
                    tRed = (1 - Alpha) * Red + Alpha * bRed
                    tGreen = (1 - Alpha) * Green + Alpha * bGreen
                    tBlue = (1 - Alpha) * Blue + Alpha * bBlue
                    SetPixel hDC, X1, i + MinY, RGB(tRed, tGreen, tBlue)
                Next i
            End If
        End IfEnd Sub
    Private Sub Command2_Click()
        DrawSmoothLine 300, 20, 40, 200, Me.hDC, RGB(120, 60, 220)
        Me.Refresh
    End Sub