Basierend auf der Inspiration von http://www.eggheadcafe.com/tutorials/aspnet/05748429-75a4-449a-9aab-82758cfb13df/animating-mandelbrot-frac.aspx habe ich mich drangesetzt ein kleines Control für die Erstellung und Berechnung von Mandelbrot-Grafiken zu erzeugen. Im Gegensatz zum Original, habe ich das Control allerdings so geschrieben, das alle Parameter über Dependancy Properties in Blend konfigurierbar und animierbar sind.

Einige Impressionen …

image image image

Das ganze lässt sich übrigens in prima in Blend über die Eigenschaften konfigurieren.

image

Der Code für das Mandelbrot-Control …

   1: using System;
   2: using System.Windows;
   3: using System.Windows.Controls;
   4: using System.Windows.Media;
   5: using System.Windows.Media.Imaging;
   6:  
   7: namespace Homepage.Fun.Mandelbrot
   8: {
   9:     public partial class MandelbrotControl : UserControl
  10:     {
  11:         public MandelbrotControl()
  12:         {
  13:             InitializeComponent();
  14:  
  15:             DrawMandelbrotSet();
  16:         }
  17:  
  18:         #region Dependancy Properties
  19:  
  20:         public double RMin 
  21:         {
  22:             get { return (double)GetValue(RMinProperty); }
  23:             set 
  24:             {
  25:                 SetValue(RMinProperty, value);
  26:                 DrawMandelbrotSet();
  27:             }
  28:         }
  29:  
  30:         public static readonly DependencyProperty RMinProperty =
  31:                 DependencyProperty.Register("RMin", typeof(double),
  32:                 typeof(MandelbrotControl),
  33:                 new PropertyMetadata(-.75,
  34:                 null));
  35:  
  36:         public double RMax
  37:         {
  38:             get { return (double)GetValue(RMaxProperty); }
  39:             set
  40:             {
  41:                 SetValue(RMaxProperty, value);
  42:                 DrawMandelbrotSet();
  43:             }
  44:         }
  45:  
  46:         public static readonly DependencyProperty RMaxProperty =
  47:                 DependencyProperty.Register("RMax", typeof(double),
  48:                 typeof(MandelbrotControl),
  49:                 new PropertyMetadata(-.46,
  50:                 null));
  51:  
  52:         public double IMin
  53:         {
  54:             get { return (double)GetValue(IMinProperty); }
  55:             set
  56:             {
  57:                 SetValue(IMinProperty, value);
  58:                 DrawMandelbrotSet();
  59:             }
  60:         }
  61:  
  62:         public static readonly DependencyProperty IMinProperty =
  63:             DependencyProperty.Register("IMin", typeof(double),
  64:             typeof(MandelbrotControl),
  65:             new PropertyMetadata(-.65,
  66:             null));
  67:  
  68:         public double IMax
  69:         {
  70:             get { return (double)GetValue(IMaxProperty); }
  71:             set
  72:             {
  73:                 SetValue(IMaxProperty, value);
  74:                 DrawMandelbrotSet();
  75:             }
  76:         }
  77:  
  78:         public static readonly DependencyProperty IMaxProperty =
  79:             DependencyProperty.Register("IMax", typeof(double),
  80:             typeof(MandelbrotControl),
  81:             new PropertyMetadata(-.50,
  82:             null));
  83:  
  84:         public int Escape
  85:         {
  86:             get { return (int)GetValue(EscapeProperty); }
  87:             set
  88:             {
  89:                 SetValue(EscapeProperty, value);
  90:                 DrawMandelbrotSet();
  91:             }
  92:         }
  93:  
  94:         public static readonly DependencyProperty EscapeProperty =
  95:                 DependencyProperty.Register("Escape", typeof(int),
  96:                 typeof(MandelbrotControl),
  97:                 new PropertyMetadata(20,
  98:                 null));
  99:  
 100:         public int Max
 101:         {
 102:             get { return (int)GetValue(MaxProperty); }
 103:             set
 104:             {
 105:                 SetValue(MaxProperty, value);
 106:                 DrawMandelbrotSet();
 107:             }
 108:         }
 109:  
 110:         public static readonly DependencyProperty MaxProperty =
 111:                 DependencyProperty.Register("Max", typeof(int),
 112:                 typeof(MandelbrotControl),
 113:                 new PropertyMetadata(30,
 114:                 null));
 115:  
 116:         public double Step
 117:         {
 118:             get { return (double)GetValue(StepProperty); }
 119:             set
 120:             {
 121:                 SetValue(StepProperty, value);
 122:                 DrawMandelbrotSet();
 123:             }
 124:         }
 125:  
 126:         public static readonly DependencyProperty StepProperty =
 127:                 DependencyProperty.Register("Step", typeof(double),
 128:                 typeof(MandelbrotControl),
 129:                 new PropertyMetadata(.002,
 130:                 null));
 131:  
 132:         public int Count
 133:         {
 134:             get { return (int)GetValue(CountProperty); }
 135:             set
 136:             {
 137:                 SetValue(CountProperty, value);
 138:                 DrawMandelbrotSet();
 139:             }
 140:         }
 141:  
 142:         public static readonly DependencyProperty CountProperty =
 143:                 DependencyProperty.Register("Count", typeof(int),
 144:                 typeof(MandelbrotControl),
 145:                 new PropertyMetadata(100,
 146:                 null));
 147:  
 148:         public int ImageWidth
 149:         {
 150:             get { return (int)GetValue(ImageWidthProperty); }
 151:             set
 152:             {
 153:                 SetValue(ImageWidthProperty, value);
 154:                 DrawMandelbrotSet();
 155:             }
 156:         }
 157:  
 158:         public static readonly DependencyProperty ImageWidthProperty =
 159:                 DependencyProperty.Register("ImageWidth", typeof(int),
 160:                 typeof(MandelbrotControl),
 161:                 new PropertyMetadata(400,
 162:                 null));
 163:  
 164:  
 165:         public int ImageHeight
 166:         {
 167:             get { return (int)GetValue(ImageHeightProperty); }
 168:             set
 169:             {
 170:                 SetValue(ImageHeightProperty, value);
 171:                 DrawMandelbrotSet();
 172:             }
 173:         }
 174:  
 175:         public static readonly DependencyProperty ImageHeightProperty =
 176:                 DependencyProperty.Register("ImageHeight", typeof(int),
 177:                 typeof(MandelbrotControl),
 178:                 new PropertyMetadata(400,
 179:                 null));
 180:  
 181:         public int PowFactor
 182:         {
 183:             get { return (int)GetValue(PowFactorProperty); }
 184:             set
 185:             {
 186:                 SetValue(PowFactorProperty, value);
 187:                 DrawMandelbrotSet();
 188:             }
 189:         }
 190:  
 191:         public static readonly DependencyProperty PowFactorProperty =
 192:                 DependencyProperty.Register("PowFactor", typeof(int),
 193:                 typeof(MandelbrotControl),
 194:                 new PropertyMetadata(5,
 195:                 null));
 196:  
 197:         public double Param1
 198:         {
 199:             get { return (double)GetValue(Param1Property); }
 200:             set
 201:             {
 202:                 SetValue(Param1Property, value);
 203:                 DrawMandelbrotSet();
 204:             }
 205:         }
 206:  
 207:         public static readonly DependencyProperty Param1Property =
 208:                 DependencyProperty.Register("Param1", typeof(double),
 209:                 typeof(MandelbrotControl),
 210:                 new PropertyMetadata(2.0,
 211:                 null));
 212:  
 213:         #endregion
 214:  
 215:         private void DrawMandelbrotSet()
 216:         {
 217:             double rmin = (double)this.GetValue(RMinProperty);
 218:             double rmax = (double)this.GetValue(RMinProperty);
 219:             double imin = (double)this.GetValue(RMinProperty);
 220:             double imax = (double)this.GetValue(RMinProperty);
 221:             
 222:             double step = (double)this.GetValue(StepProperty);
 223:             int max = (int)this.GetValue(MaxProperty);
 224:             int escape = (int)this.GetValue(EscapeProperty);
 225:  
 226:             int width = (int)GetValue(ImageWidthProperty);
 227:             int height = (int)GetValue(ImageHeightProperty);
 228:             int powFactor = (int)GetValue(PowFactorProperty);
 229:             int count = (int)this.GetValue(CountProperty);
 230:  
 231:             double param1 = (double)GetValue(Param1Property);
 232:  
 233:             rmin -= step * count;
 234:             rmax += step * count;
 235:             imin -= step * count;
 236:             imax += step * count;
 237:  
 238:             WriteableBitmap bitmap = new WriteableBitmap(width, height, PixelFormats.Bgr32);
 239:  
 240:             double dr = (rmax - rmin) / (width - 1);
 241:             double di = (imax - imin) / (height - 1);
 242:  
 243:             for (int x = 0; x < width; x++)
 244:             {
 245:                 double cr = rmin + (x * dr);
 246:                 for (int y = 0; y < height; y++)
 247:                 {
 248:                     double ci = imin + (y * di);
 249:                     double zr = cr;
 250:                     double zi = ci;
 251:                     int counter = 0;
 252:  
 253:                     while (counter < max)
 254:                     {
 255:                         double zr2 = zr * zr;
 256:                         double zi2 = zi * zi;
 257:  
 258:                         if (zr2 + zi2 > escape)
 259:                         {
 260:                             bitmap.Pixels[(y * width) + x] = (int)Math.Pow(counter + 1, powFactor) % int.MaxValue;
 261:                             break;
 262:                         }
 263:                         zi = ci + (param1 * zr * zi);
 264:                         zr = cr + zr2 - zi2;
 265:                         counter++;
 266:                     }
 267:  
 268:                     if (counter == max)
 269:                     {
 270:                         bitmap.Pixels[(y * width) + x] = 0; // Black
 271:                     }
 272:                 }
 273:             }
 274:  
 275:             _image.Source = bitmap;
 276:         }
 277:     }
 278: }