Silverlight 4 Martin Fractals with WriteableBitmapEx

While WriteableBitmap by itself is somewhat sparse in terms of methods, the WriteableBitmapEx offering provides all kinds of cool extension methods to draw on and manipulate bitmaps in Silverlight.

I've always enjoyed programming with Silverlight since version 2, and once the WriteableBitmap class came out circa version 3, things got even more interesting. While WriteableBitmap by itself is somewhat sparse in terms of methods, friend and Silverlight MVP extraordinaire Rene Schulte spearheaded the WriteableBitmapEx offering which provides all kinds of cool extension methods to draw on and manipulate bitmaps. You have SetPixel, Brightness, and virtually any kind of shape drawing method you can think of (including some I've never even heard of) - curves, lines, Bezier, Bresnehan, fills, blits, resize - you name it, Rene and his contributors have put it into the project.

Fractal geometry is another fascination of mine. With Silverlight's speed, it becomes possible to implement all kinds of iterative mathematical equations that can be plotted on a Silverlight Image object. One such pattern is the Hopalong Fractal,a sort of orbit-fractal. They are images of a simple two-dimensional iteration system. The name Hopalong is derived from the fact that such an image is built of points hopping along on an elliptical path starting from one point in the center. Hopalong orbits ( not related to Hopalong Cassidy ) were discovered by Barry Martin of Aston University, Birmingham, England. A.K. Dewdney featured the Hopalongs in "Scientific American" (1986).

The actual formula is deceptively simple:

x(n + 1) = y(n) - sign(x(n) * sqrt|b*x(n) - c
y(n + 1) = a - x(n)

Depending on the values of the parameters a, b, and c, the orbital will vary, and the image will look different. You can change the parameters and look for a pattern that you like best. There are at least two dozen similar formulae for attractors like Hopalong, each producing a different and exquisite fractal pattern.

What I've done here is actually take one of the sample projects from WriteableBitmapEx, change the name, and plug in a Hopalong class. I use the CompositionTarget.Rendering event, which fires whenever Silverlight is ready to process a new frame, to handle the call to my Paint method, which renders a new instance of the orbital on a WriteableBitmap, iterating over several thousand points on the orbit and using 32 integer colors. I also have some effects I've programmed in:

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.IO;

namespace WriteableBitmapMartinFractal
{
     public class Hopalong
    {
       int scrWidth = 480; //width of image in pixels
       static double a, b, c; //parameters that determine shape
       double diam; //area displayed
       float hue; //color of dot
       int numDots = 3000; //number of dots of each color

      public Hopalong()
     {
         setparam();
     }

     Random rand = new Random((int)DateTime.Now.Ticks);

     public void setparam()
    {
        //choose values of parameters a,b,c
       a = 8 * (rand.Next(1) - 0.8);
       b = 4 * (rand.Next(1) - 0.8);
       c = 8 * (rand.Next(1) - 0.7);
      diam = 280;
    }

    private static int clr = 0;

   public void Paint(WriteableBitmap g)
  {
      // setparam();
     double x0, y0; //bottom right corner coordinates
     double x, y, xx; //for plotting points
     int u, v; //position of dot
     double pixunit; //pixels per unit length
     pixunit = ((double)scrWidth) / diam *1.5 ;
     x = 0;
     y = 0;
     x0 = -.5 * diam;
     y0 = 0.5 * (a + diam); //center of screen is at (0,a/2).
     u = 0;
     v = 0;
    clr += 100;
    if (clr == int.MaxValue) clr = 1;
  

   for (int colorNum = 0; colorNum < 32; colorNum++)
   // draw 32 different colors
  {
      hue = (int) ((colorNum *clr) * 1000 );

      for (int i = 0; i <numDots ; i++)
     {
        xx = y - (Math.Sign(x) * Math.Sqrt(Math.Abs(b * x - c)));
       y = a - x;
        x = xx;
       u = (int)((x - x0) * pixunit);
       v = (int)((y0 - y) * pixunit);
      try
     {
        g.SetPixel(u, v, (int)hue);
     }
     catch
    {
       // oops - out of bounds, start over with new set of params
      setparam();
     }
     g.Invalidate();

   }
}

  // let's vary the number of dots too
  numDots = rand.Next(3000);

   a -= rand.Next(1)/100;
   b -= rand.Next(1) /100;
   c -= rand.Next(1) /100;
}
}
}

The rendered, constantly animating image might look like this one:



You can download the Silverlight 4 Visual Studio Solution here.

By Peter Bromberg   Popularity  (4790 Views)