The Mandelbrot set uses an iterated equation to calculate colors for the points in a region. The equation is:
Z(n) = Z(n-1)^2 + C
Here the Z(n) and C are complex numbers.
It can be shown that if the magnitude of Z(n) ever exceeds 2, then it eventually diverges towards infinity.
To find the color for the point (x, y), the program sets Z(0) = 0 and C = x + y * i. It then generates values for Z(n) until Z(n)'s magnitude exceeds 2 or it reaches some predetermined maximum number of iterations. At that point, the program uses the number of iterations it performed to assign the point's color. For example, if the program is using K colors and it performed I iterations, then it assigns the point color number I Mod K.
The following code shows how the program draws the Mandelbrot set.
|
' Draw the Mandelbrot set.
Private Sub DrawMandelbrot()
' Work until the magnitude squared > 4.
Const MAX_MAG_SQUARED = 4
Dim bitmap_info As BITMAPINFO
Dim pixels() As Byte
Dim bytes_per_scanLine As Integer
Dim pad_per_scanLine As Integer
Dim wid As Long
Dim hgt As Long
Dim clr As Long
Dim X As Integer
Dim Y As Integer
Dim ReaC As Double
Dim ImaC As Double
Dim dReaC As Double
Dim dImaC As Double
Dim ReaZ As Double
Dim ImaZ As Double
Dim ReaZ2 As Double
Dim ImaZ2 As Double
Dim r As Integer
Dim b As Integer
Dim g As Integer
picCanvas.Line (0, 0)-(picCanvas.ScaleWidth, _
picCanvas.ScaleHeight), vbBlack, BF
DoEvents
' Prepare the bitmap description.
With bitmap_info.bmiHeader
.biSize = 40
.biWidth = picCanvas.ScaleWidth
' Use negative height to scan top-down.
.biHeight = -picCanvas.ScaleHeight
.biPlanes = 1
.biBitCount = 32
.biCompression = BI_RGB
bytes_per_scanLine = ((((.biWidth * .biBitCount) + _
31) \ 32) * 4)
pad_per_scanLine = bytes_per_scanLine - (((.biWidth _
* .biBitCount) + 7) \ 8)
.biSizeImage = bytes_per_scanLine * Abs(.biHeight)
End With
' Load the bitmap's pixel data.
ReDim pixels(1 To 4, 1 To picCanvas.ScaleWidth, 1 To _
picCanvas.ScaleHeight)
GetDIBits picCanvas.hdc, picCanvas.Image, _
0, picCanvas.ScaleHeight, pixels(1, 1, 1), _
bitmap_info, DIB_RGB_COLORS
' Adjust the coordinate bounds to fit picCanvas.
AdjustAspect
' dReaC is the change in the real part
' (X value) for C. dImaC is the change in the
' imaginary part (Y value).
wid = picCanvas.ScaleWidth
hgt = picCanvas.ScaleHeight
dReaC = (m_Xmax - m_Xmin) / (wid - 1)
dImaC = (m_Ymax - m_Ymin) / (hgt - 1)
' Calculate the values.
ReaC = m_Xmin
For X = 1 To wid
ImaC = m_Ymin
For Y = 1 To hgt
ReaZ = Zr
ImaZ = Zim
ReaZ2 = Z2r
ImaZ2 = Z2im
clr = 1
Do While clr < MaxIterations And _
ReaZ2 + ImaZ2 < MAX_MAG_SQUARED
' Calculate Z(clr).
ReaZ2 = ReaZ * ReaZ
ImaZ2 = ImaZ * ImaZ
ImaZ = 2 * ImaZ * ReaZ + ImaC
ReaZ = ReaZ2 - ImaZ2 + ReaC
clr = clr + 1
Loop
clr = m_Colors(1 + clr Mod NumColors)
pixels(pixR, X, Y) = clr And &HFF&
pixels(pixG, X, Y) = (clr And &HFF00&) \ &H100&
pixels(pixB, X, Y) = (clr And &HFF0000) \ _
&H10000
ImaC = ImaC + dImaC
Next Y
ReaC = ReaC + dReaC
' Let the user know we're not dead.
If X Mod 10 = 0 Then
picCanvas.Line (0, 0)-(X, hgt), vbWhite, BF
picCanvas.Refresh
End If
Next X
' Update the image.
SetDIBits picCanvas.hdc, picCanvas.Image, _
0, picCanvas.ScaleHeight, pixels(1, 1, 1), _
bitmap_info, DIB_RGB_COLORS
picCanvas.Picture = picCanvas.Image
Caption = "Mandelbrot (" & Format$(m_Xmin, "0.000000") _
& ", " & _
Format$(m_Ymin, "0.000000") & ")-(" & _
Format$(m_Xmax, "0.000000") & ", " & _
Format$(m_Ymax, "0.000000") & ")"
End Sub
|