Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
MandelbrotSmoothFractal.cs
1using System;
2using System.Numerics;
3using System.Text;
4using SkiaSharp;
10
12{
26 {
32 : base(new ScriptNode[] { z, f, dr, Palette, DimX, DimY },
33 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
35 {
36 }
37
43 : base(new ScriptNode[] { z, f, dr, Palette, DimX },
44 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
46 {
47 }
48
53 : base(new ScriptNode[] { z, f, dr, Palette },
54 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
56 {
57 }
58
63 : base(new ScriptNode[] { z, f, dr },
64 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar }, Start, Length, Expression)
65 {
66 }
67
71 public override string[] DefaultArgumentNames
72 {
73 get
74 {
75 return new string[] { "z", "f", "dr", "Palette", "DimX", "DimY" };
76 }
77 }
78
83 {
84 string ColorExpression = null;
85 SKColor[] Palette;
86 double rc, ic;
87 double dr;
88 int dimx, dimy;
89 int i, c;
90 object Obj;
91 ScriptNode fDef = null;
92 c = Arguments.Length;
93 i = 0;
94
95 Obj = Arguments[i++].AssociatedObjectValue;
96 if (Obj is Complex z)
97 {
98 rc = z.Real;
99 ic = z.Imaginary;
100 }
101 else
102 {
103 rc = Expression.ToDouble(Obj);
104 ic = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
105 }
106
107 if (i >= c)
108 throw new ScriptRuntimeException("Insufficient parameters in call to MandelbrotTopographyFractal().", this);
109
110 Obj = Arguments[i].AssociatedObjectValue;
111 if (Obj is ILambdaExpression f)
112 {
113 fDef = this.Arguments[i++];
114
115 if (f.NrArguments != 2)
116 throw new ScriptRuntimeException("Lambda expression in calls to MandelbrotTopographyFractal() must be of two variables (z,c).", this);
117 }
118 else
119 {
120 f = null;
121 fDef = null;
122
123 if (Obj is null)
124 i++;
125 }
126
127 dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
128
129 if (i < c && !(this.Arguments[i] is null) && Arguments[i] is ObjectVector)
130 {
131 ColorExpression = this.Arguments[i].SubExpression;
133 }
134 else
135 {
136 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(1024, 16, out int Seed, this, Variables);
137 ColorExpression = "RandomLinearAnalogousHSL(1024,16," + Seed.ToString() + ")";
138
139 if (i < c && this.Arguments[i] is null)
140 i++;
141 }
142
143 if (i < c)
144 dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
145 else
146 dimx = 320;
147
148 if (i < c)
149 dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
150 else
151 dimy = 200;
152
153 if (i < c)
154 {
155 throw new ScriptRuntimeException("Parameter mismatch in call to MandelbrotSmoothFractal(r,c,dr[,Palette][,dimx[,dimy]]).",
156 this);
157 }
158
159 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
160 throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
161
162 if (!(f is null))
163 {
164 return CalcMandelbrot(rc, ic, dr, f, Variables, Palette, dimx, dimy, this, this.FractalZoomScript,
165 new object[] { Palette, dimx, dimy, ColorExpression, fDef });
166 }
167 else
168 {
169 return CalcMandelbrot(rc, ic, dr, Palette, dimx, dimy, this, Variables, this.FractalZoomScript,
170 new object[] { Palette, dimx, dimy, ColorExpression, fDef });
171 }
172 }
173
174 private string FractalZoomScript(double r, double i, double Size, object State)
175 {
176 object[] Parameters = (object[])State;
177 int DimX = (int)Parameters[1];
178 int DimY = (int)Parameters[2];
179 string ColorExpression = (string)Parameters[3];
180 ScriptNode f = (ScriptNode)Parameters[4];
181
182 StringBuilder sb = new StringBuilder();
183
184 sb.Append("MandelbrotSmoothFractal((");
185 sb.Append(Expression.ToString(r));
186 sb.Append(',');
187 sb.Append(Expression.ToString(i));
188 sb.Append("),");
189
190 if (!(f is null))
191 sb.Append(f.SubExpression);
192
193 sb.Append(',');
194 sb.Append(Expression.ToString(Size / 4));
195
196 if (!string.IsNullOrEmpty(ColorExpression))
197 {
198 sb.Append(',');
199 sb.Append(ColorExpression);
200 }
201
202 sb.Append(',');
203 sb.Append(DimX.ToString());
204 sb.Append(',');
205 sb.Append(DimY.ToString());
206 sb.Append(')');
207
208 return sb.ToString();
209 }
210
214 public static FractalGraph CalcMandelbrot(double rCenter, double iCenter, double rDelta,
215 SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables,
216 FractalZoomScript FractalZoomScript, object State)
217 {
218 double r0, i0, r1, i1;
219 double dr, di;
220 double r, i;
221 double zr, zi, zrt, zr2, zi2;
222 double aspect;
223 int x, y;
224 int n, N;
225
226 N = Palette.Length;
227
228 int Size = Width * Height;
229 double[] ColorIndex = new double[Size];
230 int Index = 0;
231
232 rDelta *= 0.5;
233 r0 = rCenter - rDelta;
234 r1 = rCenter + rDelta;
235
236 aspect = ((double)Width) / Height;
237
238 i0 = iCenter - rDelta / aspect;
239 i1 = iCenter + rDelta / aspect;
240
241 dr = (r1 - r0) / Width;
242 di = (i1 - i0) / Height;
243
244 for (y = 0, i = i0; y < Height; y++, i += di)
245 {
246 for (x = 0, r = r0; x < Width; x++, r += dr)
247 {
248 zr = r;
249 zi = i;
250
251 n = 0;
252 zr2 = zr * zr;
253 zi2 = zi * zi;
254
255 while (zr2 + zi2 < 9 && n < N)
256 {
257 n++;
258 zrt = zr2 - zi2 + r;
259 zi = 2 * zr * zi + i;
260 zr = zrt;
261
262 zr2 = zr * zr;
263 zi2 = zi * zi;
264 }
265
266 if (n >= N)
267 ColorIndex[Index++] = N;
268 else
269 ColorIndex[Index++] = n;
270 }
271 }
272
273 Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
274
275 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
276 FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
277
278 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
279 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
280 }
281
285 public static FractalGraph CalcMandelbrot(double rCenter, double iCenter, double rDelta,
286 ILambdaExpression f, Variables Variables, SKColor[] Palette, int Width, int Height,
287 ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
288 {
289 double r0, i0, r1, i1;
290 double dr, di;
291 double r, i, Mod;
292 double aspect;
293 int x, x2, y;
294 int n, N;
295
296 N = Palette.Length;
297
298 int Size = Width * Height;
299 double[] ColorIndex = new double[Size];
300
301 Complex z;
302 IElement[] P = new IElement[2];
303 int j, c;
304 IElement Obj;
305
306 rDelta *= 0.5;
307 r0 = rCenter - rDelta;
308 r1 = rCenter + rDelta;
309
310 aspect = ((double)Width) / Height;
311
312 i0 = iCenter - rDelta / aspect;
313 i1 = iCenter + rDelta / aspect;
314
315 dr = (r1 - r0) / Width;
316 di = (i1 - i0) / Height;
317
318 for (y = 0, i = i0; y < Height; y++, i += di)
319 {
320 Complex[] Row = new Complex[Width];
321 Complex[] Row0 = new Complex[Width];
322 int[] Offset = new int[Width];
323
324 c = Width;
325 for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++)
326 {
327 Row[x] = Row0[x] = new Complex(r, i);
328 Offset[x] = x2;
329 }
330
331 Variables v = new Variables();
332 Variables.CopyTo(v);
333
334 n = 0;
335 while (n < N && c > 0)
336 {
337 n++;
338 P[0] = new ComplexVector(Row);
339 P[1] = Expression.Encapsulate(Row0);
340 Obj = f.Evaluate(P, v);
341 Row = Obj.AssociatedObjectValue as Complex[];
342
343 if (Row is null)
344 {
345 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
346 "and return complex vectors of equal length. Type returned: " +
347 Obj.GetType().FullName, Node);
348 }
349 else if (Row.Length != c)
350 {
351 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
352 "and return complex vectors of equal length. Length returned: " +
353 Row.Length.ToString() + ". Expected: " + c.ToString(), Node);
354 }
355
356 for (x = x2 = 0; x < c; x++)
357 {
358 z = Row[x];
359 j = Offset[x];
360
361 Mod = z.Magnitude;
362
363 if (Mod < 3)
364 {
365 if (x != x2)
366 {
367 Row[x2] = z;
368 Row0[x2] = Row0[x];
369 Offset[x2] = j;
370 }
371
372 x2++;
373 }
374 else
375 {
376 if (n >= N)
377 ColorIndex[j++] = N;
378 else
379 ColorIndex[j++] = n;
380 }
381 }
382
383 if (x2 < x)
384 {
385 Array.Resize(ref Row, x2);
386 Array.Resize(ref Row0, x2);
387 Array.Resize(ref Offset, x2);
388 c = x2;
389 }
390 }
391
392 if (c > 0)
393 {
394 for (x = 0; x < c; x++)
395 {
396 j = Offset[x];
397 ColorIndex[j] = N;
398 }
399 }
400
401 }
402
403 Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
404
405 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
406 FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
407
408 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
409 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
410 }
411
415 public override string FunctionName => nameof(MandelbrotSmoothFractal);
416
417 }
418}
Class managing a script expression.
Definition: Expression.cs:39
static IElement Encapsulate(object Value)
Encapsulates an object.
Definition: Expression.cs:4955
static double ToDouble(object Object)
Converts an object to a double value.
Definition: Expression.cs:4824
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Definition: Expression.cs:4496
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
static FractalGraph CalcMandelbrot(double rCenter, double iCenter, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
MandelbrotSmoothFractal(ScriptNode z, ScriptNode f, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
static FractalGraph CalcMandelbrot(double rCenter, double iCenter, double rDelta, ILambdaExpression f, Variables Variables, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
MandelbrotSmoothFractal(ScriptNode z, ScriptNode f, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
MandelbrotSmoothFractal(ScriptNode z, ScriptNode f, ScriptNode dr, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
MandelbrotSmoothFractal(ScriptNode z, ScriptNode f, ScriptNode dr, int Start, int Length, Expression Expression)
TODO
Defines a clickable fractal graph in the complex plane.
Definition: FractalGraph.cs:22
static PixelInformation ToPixels(double[] ColorIndex, int Width, int Height, SKColor[] Palette)
TODO
static SKColor[] ToPalette(ObjectVector Vector)
TODO
static double[] FindBoundaries(double[] ColorIndex, int Width, int Height)
TODO
static void Smooth(double[] ColorIndex, double[] Boundary, int Width, int Height, int N, SKColor[] Palette, ScriptNode Node, Variables Variables)
TODO
Handles bitmap-based graphs.
Definition: GraphBitmap.cs:13
Base class for multivariate funcions.
ScriptNode[] Arguments
Function arguments.
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
string SubExpression
Sub-expression defining the node.
Definition: ScriptNode.cs:183
Expression Expression
Expression of which the node is a part.
Definition: ScriptNode.cs:177
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
Collection of variables.
Definition: Variables.cs:25
void Preview(Expression Expression, IElement Result)
Reports a preview of the final result.
Definition: Variables.cs:455
void CopyTo(Variables Variables)
Copies available variables to another variable collection.
Definition: Variables.cs:400
Basic interface for all types of elements.
Definition: IElement.cs:20
Base interface for lambda expressions.
IElement Evaluate(IElement[] Arguments, Variables Variables)
Evaluates the lambda expression.
delegate string FractalZoomScript(double r, double i, double Size, object State)
Generates new script when zoomed.
ArgumentType
Type of parameter used in a function definition or a lambda definition.
Definition: IFunction.cs:9