Mandelbrot mit Silverlight 3

Basierend auf der Inspiration von https://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: }