Skip to main content

Chaos in WPF

feigenbaum_2I’ve been reading up on math lately. Mostly chaos theory and nonlinear dynamics. I still don’t get why they don’t teach stuff like this in school, I might have even found math fun if they had done so, part of the fun of these areas of mathematics are the cool graphics they produce. Everyone knows the Mandelbrot set, but in this post I want to focus more on chaos theory. And to make it interesting for my usual readers lets draw some pictures with WPF

But first some math to scare off all the wanna-be geeks out there. We’re going to have a look at the logistic map.

xn+1 = xnr(1 – xn)

This function was thought up by the mathematician Pierre François Verhulst to model population growth. The function models two things, bigger populations grow faster until they get too big, then growth will be limited by competition for resources. When you look at the function you will see that it’s a non-linear difference equation.

The fun starts when you start playing with r. For small values of r the x will quickly go to zero and stay there. Things get more interesting for r > 1, first x will stabilize on some value. The stable value for x gets bigger as r gets bigger, but for values of r bigger than 3 x will actually start to oscillate, first between 2 values, then between 4 values, then 8 and then the behaviour of x will become chaotic. You can plot this out and you will get a nice fractal-image. If you zoom in on part of the image you will see the same image repeated.

I wanted to see if I could plot this. My previous toy project was done with WinForms but I found drawing pixels a bit cumbersome. This time I wanted to try out WPF. I found that drawing single pixels in WPF is not trivial either but with a little help from the WriteableBitmap component I could access single pixels in a bitmap. I’d like to have a simple panel component that I can reuse for simple toy projects like this so I quickly built a nice BitmapPanel. Here’s the interface definition. The source code for it is included in the project files if you want to see how it works.

   1: public interface IBitmapPanel
   2: {
   3:     int PixelWidth { get; }
   4:     int PixelHeight { get; }
   5:  
   6:     event Action Redraw;
   7:  
   8:     void SetPixel(int x, int y, byte color);
   9:     byte GetPixel(int x, int y);
  10: }

You get redraw events every time the panel changes shape. You can retrieve the size of the panel and you can get and set pixels. Simple enough but usable.


I now could put the bitmap panel on a window and build a presenter object around it. The presenter is where all the interesting stuff happens, it looks like this:



   1: public class ChaosPresenter
   2: {
   3:     public IBitmapPanel View { get; set;}
   4:     
   5:     public void Initialize()
   6:     {
   7:         View.Redraw += RedrawHandler;
   8:     }
   9:  
  10:     private void RedrawHandler()
  11:     {
  12:         var width = View.PixelWidth;
  13:  
  14:         for (var i = 0; i < width; i++)
  15:         {
  16:             var factor = i*3f/width + 1;
  17:             Iterate(i, factor);
  18:         }
  19:     }
  20:  
  21:     void SetPixelScaleY(int x, float y)
  22:     {
  23:         var ycoordinate = (int)((1.0f - y) * View.PixelHeight);
  24:         var index = x + ycoordinate * View.PixelWidth;
  25:         View.SetPixel(x, ycoordinate, (byte)((View.GetPixel(x, ycoordinate) + 0xFF) / 2));
  26:     }
  27:  
  28:     private void Iterate(int x, float factor)
  29:     {
  30:         var number = .2f;
  31:  
  32:         for(var i = 0; i < 100; i++)
  33:         {
  34:             number = GetNextIteration(factor, number);
  35:         }
  36:  
  37:         for(var i = 0; i < 1000; i++)
  38:         {
  39:             SetPixelScaleY(x, number);
  40:             number = GetNextIteration(factor, number);
  41:         }
  42:     }
  43:  
  44:     private float GetNextIteration(float factor, float value)
  45:     {
  46:         return factor*value*(1f -value);
  47:     }
  48: }

It wraps the IBitmapPanel and redraws the complete diagram every time it resizes. The RedrawHandler is where stuff happens. It maps different values for r between 1 and 4 on the x axis of the bitmap panel and calls Iterate for all those values of r. Iterate starts at x = 0.2 and throws away the first 100 iterations. This allows x to stabilize into the typical behavior for that value of r. Then it iterates through the next 1000 values and plots them.  GetNextIteration is my implementation of the logistic function. You can play with the values in Iterate if you like. By changing the number of iterations on line 32 you can see how quicly x settles in it’s typical behaviour for different values of r for example. I got the image at the start of this post by iterating 10 times before starting to plot. You can see that x settles pretty quick for most values of r, but near r = 1 and r = 3 it takes more iterations for x to settle down.


The executable can be downloaded here: ChaosExecutable.zip (5.43 kb)


And code is available here: Chaos.zip (10.36 kb)

Comments

Popular posts from this blog

Using xUnit.Net with .Net 4.0

I’ve been using xUnit.Net for a while now. It’s just a tiny bit cleaner and slightly less abrasive than other .Net unit testing frameworks. Leaving out unnecessary stuff like [TestFixture] and shortening Assert.AreEqual to the equally clear but shorter Assert.Equal don’t seem like big improvements but when you type them several times a day tiny improvements start to add up. I also like the use of the [Fact] attribute instead of [Test]. It shifts the focus from testing to defining behavior. So how do we get all this goodness working with the Visual Studio 2010 beta?

Running a Git repository on Ubuntu using Gitosis

20I’ve been using Git for a couple of small projects that I’ve been hosting on github.com but version control for my bigger ‘secret’ projects still runs on a windows machine with visual svn server.Now that I’m starting to use Mono for a couple of projects so I’m playing with linux more. Last week I decided to try to try out gitosis on an ubuntu server. I found out it’s pretty easy to use when you know your way around git but for a noob like me some things weren’t immediately clear. Eventually I solved most problems I ran into, so I decided to write up the steps I took to install gitosis on ubuntu 10.04

Android development resource links

I've been playing with the Android SDK and I have a growing list of bookmarks to Android dev resources for my own use. I thought the best place to keep them would be here on my blog. That way other people can benefit too. I'll keep updating this list so feel free to add suggestions in the comments.