Home Search   What's New Index Books Links Q & A Newsletter Banners   Feedback Tip Jar MSDN Visual Basic Community

Title Draw a Buddhabrot color map fractal in Visual Basic 2005 This example shows how to draw a Buddhabrot color map fractal in Visual Basic .NET. fractal, buddhabrot color map, buddhabrot, mandelbrot, iterated system Graphics, Algorithms

The Mandelbrot set iterates the function Z = Z^2 + C in complex numbers for various values of C. It can be shown that, if the magnitude of Z ever grows beyond 2, then the function eventually heads towards infinity. To draw a Mandelbrot set, you iterate the function and see how many iterations it takes for the function to reach magnitude 2. You then color the point C beased on how many iterations it took. For example, if you use N colors and it took M iterations, then you could color the point M mod N.

To draw the Buddhabrot, you iterate Z = Z^2 + C for values of as usual, except you pick the values C randomly. If the function's magnitude exceeds 2 at some point, you go back and iterate the function again. This time you increment a count for each value Z that you come to before the magnitude exceeds 2. When you're done, you set a pixel's brightness to be 255 times its hit count divided by the largest hit count of any pixel.

To get the color map version, you set each point in the sequence based on the color of the initial value C. In this example, the program makes the points red if the distance from C to the origin is less than 1, green if the distance from C to the origin is less than Sqr(2), and blue otherwise.

```' Draw the Buddhabrot until stopped or
' we plot the desired number of points.
Private Sub DrawBrot()
' Get parameters.
Dim wid As Integer = Val(txtWidth.Text)
Dim hgt As Integer = Val(txtHeight.Text)
Dim cut_r As Integer = Val(txtRedCutoff.Text)
Dim cut_g As Integer = Val(txtGreenCutoff.Text)
Dim cut_b As Integer = Val(txtBlueCutoff.Text)
Dim stop_after As Integer = Val(txtStopAfter.Text)
Dim draw_every As Integer = Val(txtDrawEvery.Text)

If wid <= 0 OrElse hgt <= 0 Then
MessageBox.Show("Invalid parameter", "Error", _
MessageBoxButtons.OK, _
MessageBoxIcon.Exclamation)
Exit Sub
End If

' Make hit count arrays.
Dim hit_r(wid - 1, hgt - 1) As Integer
Dim hit_g(wid - 1, hgt - 1) As Integer
Dim hit_b(wid - 1, hgt - 1) As Integer

' Make the bitmap.
m_Bitmap = New Bitmap(wid, hgt)
picCanvas.Image = m_Bitmap
Me.ClientSize = New Size( _
picCanvas.Left + picCanvas.Width + 8, _
System.Math.Max( _
btnDraw.Top + btnDraw.Height, _
picCanvas.Top + picCanvas.Height) + 8)
mnuFileSave.Enabled = True

' Start drawing.
Dim start_time As Date = Now
Dim stop_time As Date
Dim elapsed As TimeSpan
m_Drawing = True

' Build the hit counts.
Dim dx As Double = (Wxmax - Wxmin) / hgt
Dim dy As Double = (Wymax - Wymin) / wid
Dim max_r, max_g, max_b, hits, total_hits As Integer

Do While total_hits < stop_after
Dim cx As Double = Wxmin + m_Rand.NextDouble() * _
(Wxmax - Wxmin)
Dim cy As Double = Wymin + m_Rand.NextDouble() * _
(Wymax - Wymin)
Dim dd As Double = cx * cx + cy * cy
If dd < 1 Then
DrawPoint(cx, cy, wid, hgt, dx, dy, max_r, _
hit_r, cut_r, hits)
ElseIf dd < 2 Then
DrawPoint(cx, cy, wid, hgt, dx, dy, max_g, _
hit_g, cut_g, hits)
Else
DrawPoint(cx, cy, wid, hgt, dx, dy, max_b, _
hit_b, cut_b, hits)
End If

If hits >= draw_every Then
total_hits += hits
hits = 0
DisplayBrot(wid, hgt, max_r, max_g, max_b, _
hit_r, hit_g, hit_b)

stop_time = Now
elapsed = stop_time.Subtract(start_time)
Me.Text = elapsed.TotalSeconds.ToString("0.00") _
& " sec, " & _
total_hits.ToString & " hits"

Application.DoEvents()
If Not m_Drawing Then Exit Do
End If
Loop
End Sub

' Plot one point.
Private Sub DrawPoint(ByVal cx As Double, ByVal cy As _
Double, ByVal wid As Integer, ByVal hgt As Integer, _
ByVal dx As Double, ByVal dy As Double, ByRef max_hits _
As Integer, ByVal hits(,) As Integer, ByVal cutoff As _
Integer, ByRef num_hits As Integer)
Const ESCAPING As Double = 4D

' Pick C.
''Dim cx As Double = Wxmin + m_Rand.NextDouble() *
' (Wxmax - Wxmin)
''Dim cy As Double = Wymin + m_Rand.NextDouble() *
' (Wymax - Wymin)

' Zet Z0.
Dim x, xx, y, yy As Double
x = cx
y = cy
xx = x * x
yy = y * y

' Iterate.
For i As Integer = 1 To cutoff
y = 2 * x * y + cy
x = xx - yy + cx
xx = x * x
yy = y * y
If xx + yy >= ESCAPING Then Exit For
Next i

' See if we escaped.
If xx + yy >= ESCAPING Then
' Plot.
x = cx
y = cy
xx = x * x
yy = y * y

' Iterate.
For i As Integer = 1 To cutoff
Dim ix As Integer = CInt((x - Wxmin) / dx)
Dim iy As Integer = CInt((y - Wymin) / dy)
If (ix >= 0) AndAlso (ix < hgt) AndAlso (iy >= _
0) AndAlso (iy < wid) Then
hits(iy, ix) += 1
If max_hits < hits(iy, ix) Then max_hits = _
hits(iy, ix)
Else
Exit For
End If

y = 2 * x * y + cy
x = xx - yy + cx
xx = x * x
yy = y * y
If xx + yy >= ESCAPING Then Exit For
Next i

num_hits += 1
End If
End Sub

' Draw the current image.
Private Sub DisplayBrot(ByVal wid As Integer, ByVal hgt As _
Integer, ByVal max_r As Integer, ByVal max_g As _
Integer, ByVal max_b As Integer, ByVal hit_r(,) As _
Integer, ByVal hit_g(,) As Integer, ByVal hit_b(,) As _
Integer)
Dim gr As Graphics = Graphics.FromImage(m_Bitmap)
gr.Clear(Color.Black)

Dim scale_r As Double = 255 * 2.5 / max_r
Dim scale_g As Double = 255 * 2.5 / max_g
Dim scale_b As Double = 255 * 2.5 / max_b

For y As Integer = 0 To hgt - 1
For x As Integer = 0 To wid - 1
Dim r As Integer = CInt(hit_r(x, y) * scale_r)
If r > 255 Then r = 255
Dim g As Integer = CInt(hit_g(x, y) * scale_g)
If g > 255 Then g = 255
Dim b As Integer = CInt(hit_b(x, y) * scale_b)
If b > 255 Then b = 255

m_Bitmap.SetPixel(x, y, Color.FromArgb(255, r, _
g, b))
Next x
Next y

picCanvas.Refresh()
End Sub```

 Copyright © 1997-2006 Rocky Mountain Computer Consulting, Inc.   All rights reserved. Updated