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.