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