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?

Square One available on the Android market

This is just a short post to let you know that a first version of the Android app I’ve been working on for the last couple of weeks is available on the Android market. The app is called Square One and it’s a simple bassline synthesizer. It’s free so try it out and let me know what you think of it, but be prepared it’s still an early version. I hope to add more features in the next few months and maybe build something that can be used to create real music.The lower part of the screen contains the sequencer controls that can be used to program your own bass lines. On the left is a four by four grid of buttons where you can select a step in the sequence. On the right you can select the note to be played on that step. When you’re done you can press Start and the sequence starts playing. The knobs on the top can be used to control a couple of parameters from the synthesizer engine that creates the sound. You can control the cutoff frequency and resonance of the low-pass filter, attack and …

Building Android projects with Jenkins, Ant and Mercurial

I have recently set up a Jenkins build server for my Android projects hosted on Bitbucket. It’s not difficult but there are a couple pitfalls and the information on how to do this isn’t available from one single place so I decided to document the process and put up the information over here. Maybe other people will benefit from having a step-by-step guide too.