Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleDraw a Buddhabrot fractal in Visual Basic 6
DescriptionThis example shows how to draw a Buddhabrot fractal in Visual Basic 6.
Keywordsfractal, buddhabrot, mandelbrot, iterated system
CategoriesGraphics, 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 color, you plot three random points, one each for red, green, and blue. When you're finished, you calculate the brightness for each pixel separately and cobine them.

 
Private Const Wxmin As Double = -2
Private Const Wxmax As Double = 1
Private Const Wymin As Double = -1.5
Private Const Wymax As Double = 1.5

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

    If (wid <= 0) Or (hgt <= 0) Then
        MsgBox "Invalid parameter", vbOKOnly Or _
            vbExclamation, "Error"
        Exit Sub
    End If

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

    ' Make the bitmap.
    picCanvas.Width = wid + picCanvas.Width - _
        picCanvas.ScaleWidth
    picCanvas.Height = hgt + picCanvas.Height - _
        picCanvas.ScaleHeight

    ' Start drawing.
    Dim start_time As Single
    Dim stop_time As Single
    Dim elapsed As Single
    start_time = Timer
    m_Drawing = True

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

    Do While total_hits < stop_after
        DrawPoint wid, hgt, dx, dy, max_r, hit_r, cut_r, _
            hits
        DrawPoint wid, hgt, dx, dy, max_g, hit_g, cut_g, _
            hits
        DrawPoint wid, hgt, dx, dy, max_b, hit_b, cut_b, _
            hits

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

            stop_time = Timer
            elapsed = stop_time - start_time
            Me.Caption = Format$(elapsed, "0.00") & " sec, " & _
                "" & _
                Format$(total_hits) & " hits"

            DoEvents
            If Not m_Drawing Then Exit Do
        End If
    Loop
End Sub

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

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

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

    ' Iterate.
    Dim i As Integer
    For i = 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 = 1 To cutoff
            Dim ix As Integer
            Dim iy As Integer
            ix = CInt((x - Wxmin) / dx)
            iy = CInt((y - Wymin) / dy)
            If (ix >= 0) And (ix < hgt) And (iy >= 0) And _
                (iy < wid) Then
                hits(iy, ix) = 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 = 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, hit_r() As Integer, _
     hit_g() As Integer, hit_b() As Integer)
    picCanvas.Cls

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

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

            picCanvas.PSet (x, y), RGB(r, g, b)
        Next x
    Next y

    picCanvas.Refresh
End Sub

Private Sub Form_Load()
    Me.ScaleMode = vbPixels
    picCanvas.ScaleMode = vbPixels
    picCanvas.AutoRedraw = True

    Randomize
    m_Drawing = False
End Sub
 
 
Copyright © 1997-2006 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated