Search EggHeadCafe's Job Board
EggHeadCafe Silverlight WPF ASP.NET VB.NET C# Excel SQL Server SharePoint
search
MicrosoftArticlesForumsFAQs
C# .NET
VB.NET
Visual Studio .NET
ADO.NET
Xml / Xslt
VB 6.0
.NET CF
GDI+
LINQ
Deployment
Security
FoxPro
Silverlight / WPF
Entity Framework
RIA Services

WebArticlesForumsFAQs
JavaScript
ASP
ASP.NET
WCF

DatabasesArticlesForumsFAQs
SQL Server
Access
Oracle
MySQL
Other Databases

OfficeArticlesForumsFAQs
Excel
Word
Powerpoint
Outlook
Publisher
Money

Non-MicrosoftArticlesForumsFAQs
NHibernate
Perl
PHP
Ruby
Java
Linux / Unix
Apple
Open Source

Operating SysArticlesForumsFAQs
Windows 7
Windows Server
Windows Vista
Windows XP
Windows Update
MAC
Linux / UNIX

Server PlatformsArticlesForumsFAQs
BizTalk
Site Server
Exhange Server
IIS

Graphic DesignArticlesForumsFAQs
Macromedia Flash
Adobe PhotoShop
Expression Blend
Expression Design
Expression Web

OtherArticlesForumsFAQs
Lounge
Subversion / CVS
Ask Dr. Dotnetsky
Active Directory
Networking
Uninstall Virus
Job Openings
Product Reviews
Search Engines
Resumes

 

Animating Mandelbrot fractals with Silverlight 3 WriteableBitmap


By Peter Bromberg
Printer Friendly Version
View My Articles
110 Views
    

Use the new WriteableBitmap class in Silverlight 3 Beta to render an animated zooming Mandelbrot Set fractal image.


I've been a student of fractal geometry for many years. Benoit Mandelbrot is considered the "father" of modern fractals. When his book "The Fractal geometry of Nature" was published in 1982, I bought a copy. This is a coffee-table style book with a huge amount of information about the history of fractals, mathematical formulae, and is loaded with stunning color pictures of computer -generated fractals of all types. To this day, it remains the seminal work on fractal geometry.

Fractals are realistic and useful models of many phenomena in the real world. Natural fractals include the shapes of mountains, coastlines and river basins; the structures of plants, blood vessels and lungs; the clustering of galaxies; and Brownian motion. Fractals are found in human pursuits, such as music, painting, architecture, and stock market prices.

In Silverlight 3, we have the addition of the WriteableBitmap class, which enables the manipulation of the pixels in an image, as well as to create transforms that can be used to create reflections and similar effects. Even with some complex number math and many iterations involved, this class will render a bitmap of say 480 X 360 pixels of the computed Mandelbrot Set in around 120 milliseconds, making it a candidate for animation of small bitmaps in Silverlight.

To test this out, I took some C# Mandelbrot Set code and put it into an animation timeline generated through the use of the DispatcherTimer. Each time the timer Tick event fires, I increment the viewport dimensions by a small amount and regenerate the corresponding view of the Mandelbrot Set. This results in an animation that appears to the user that you are slowly zooming away from the original subset view until after a minute or so you can see the entire Mandelbrot Set mathematical domain.

This is Silverlight 3 Beta code, so I can't provide a live sample. But if you're getting into Silverlight 3, you can download the working solution below and play around with it.

Here is the class in its entirety:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace WriteableBitmap
{
    public partial class MainPage : UserControl
    {
        private System.Windows.Threading.DispatcherTimer tmr = new DispatcherTimer();
       
        private int _max = 30;
        private int _escape = 20;

        double rmin = -.75;
        double rmax = -.46;
        double imin = -.65;
        double imax = -.50;
        public MainPage()
        {
            InitializeComponent();
            tmr.Interval = TimeSpan.FromTicks(0);
            tmr.Tick += new EventHandler(tmr_Tick);
            tmr.Start();
        }

        void tmr_Tick(object sender, EventArgs e)
        {
            rmin -= .002;
            rmax += .002;
            imin -= .002;
            imax += .002;

            DrawMandelbrotSet(this.image1, rmin, rmax, imin, imax, 480,360);
        }

        private void DrawMandelbrotSet(Image image, double rmin, double rmax,
                                    double imin, double imax, int width, int height)
        {
        // uncomment next line and 3 lines at bottom to see rendering time in output window
          //  DateTime start = DateTime.Now;
            // Silverlight 2 - you can use Joe Stegman's WriteableBitmap class separately
            System.Windows.Media.Imaging.WriteableBitmap bitmap =
                new System.Windows.Media.Imaging.WriteableBitmap(width, height, PixelFormats.Bgr32);
            bitmap.Lock();
            
            double dr = (rmax - rmin) / (width - 1);
            double di = (imax - imin) / (height - 1);

            for (int x = 0; x < width; x++)
            {
                double cr = rmin + (x * dr);
                for (int y = 0; y < height; y++)
                {
                    double ci = imin + (y * di);
                    double zr = cr;
                    double zi = ci;
                    int count = 0;

                    while (count < _max)
                    {
                        double zr2 = zr * zr;
                        double zi2 = zi * zi;

                        if (zr2 + zi2 > _escape)
                        {
                            bitmap[(y*width) + x] = (int) Math.Pow(count + 1, 5) % int.MaxValue; 
                           break;
                        }
                        zi = ci + (2.0 * zr * zi);
                        zr = cr + zr2 - zi2;
                        count++;
                    }

                    if (count == _max)
                        bitmap[(y * width) + x] = 0; // Black
                }
            }
            
           bitmap.Invalidate();
            bitmap.Unlock();
            image1.Source = bitmap;
         //   DateTime end = DateTime.Now;
          //  TimeSpan elapsed = end - start;
           // System.Diagnostics.Debug.WriteLine( elapsed.TotalMilliseconds.ToString() );
        }

    }
}
Here's a small screen cap of the view when it first starts animating:



And here is the same image after it has been zooming out for 30 seconds or so:



If you want to play around with the speed and resolution, try changing the _max and _escape values.  By the way, this is a real memory hog, it may be leaky: don't be surprised if you get out of memory errors from "playing too hard"!

You can download the Visual Studio 2008 Silverlight 3 Beta Solution here.

Biography - Peter Bromberg
Peter Bromberg is a C# MVP, MCP, and .NET expert who has worked in banking, financial and telephony for over 20 years. Pete focuses exclusively on the .NET Platform, and currently develops SOA and other .NET applications for a Fortune 500 clientele. Peter enjoys producing digital photo collage with Maya,playing jazz flute, the beach, and fine wines. You can view Peter's UnBlog and IttyUrl sites.
Please post questions at forums, not via email!

button
Article Discussion: Animating Mandelbrot fractals with Silverlight 3 WriteableBitmap
Peter Bromberg posted at Friday, March 27, 2009 11:58 AM
Original Article