使用双线性插值的方法可以使得绘制的直线相对光滑一些,简单原理说明的代码如下: 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
问题解决了,用双线性插值的方法效率还是很高的。这个是绘制宽度为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
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
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
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