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 anti-Buddhabrot fractal in Visual Basic 2005
DescriptionThis example shows how to draw an anti-Buddhabrot fractal in Visual Basic .NET.
Keywordsfractal, anti-buddhabrot, 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 an anti-Buddhabrot, you look for points with magnitude that does not exceed 2 and you plot their values as before.

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.

 
' 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
        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 += 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 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