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 …
Das ganze lässt sich übrigens in prima in Blend über die Eigenschaften konfigurieren.
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: }