Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
MandelbrotSmoothGradientFractal.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 MandelbrotSmoothGradientFractal(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("MandelbrotSmoothGradientFractal((");
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 FractalGraph.Diff(ColorIndex, Width, Height, out double[] dx, out double[] dy);
278 FractalGraph.Angle(ColorIndex, Width, Height, N, dx, dy);
279
280 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
281 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
282 }
283
287 public static FractalGraph CalcMandelbrot(double rCenter, double iCenter, double rDelta,
288 ILambdaExpression f, Variables Variables, SKColor[] Palette, int Width, int Height,
289 ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
290 {
291 double r0, i0, r1, i1;
292 double dr, di;
293 double r, i, Mod;
294 double aspect;
295 int x, x2, y;
296 int n, N;
297
298 N = Palette.Length;
299
300 int Size = Width * Height;
301 double[] ColorIndex = new double[Size];
302
303 Complex z;
304 IElement[] P = new IElement[2];
305 int j, c;
306 IElement Obj;
307
308 rDelta *= 0.5;
309 r0 = rCenter - rDelta;
310 r1 = rCenter + rDelta;
311
312 aspect = ((double)Width) / Height;
313
314 i0 = iCenter - rDelta / aspect;
315 i1 = iCenter + rDelta / aspect;
316
317 dr = (r1 - r0) / Width;
318 di = (i1 - i0) / Height;
319
320 for (y = 0, i = i0; y < Height; y++, i += di)
321 {
322 Complex[] Row = new Complex[Width];
323 Complex[] Row0 = new Complex[Width];
324 int[] Offset = new int[Width];
325
326 c = Width;
327 for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++)
328 {
329 Row[x] = Row0[x] = new Complex(r, i);
330 Offset[x] = x2;
331 }
332
333 Variables v = new Variables();
334 Variables.CopyTo(v);
335
336 n = 0;
337 while (n < N && c > 0)
338 {
339 n++;
340 P[0] = new ComplexVector(Row);
341 P[1] = Expression.Encapsulate(Row0);
342 Obj = f.Evaluate(P, v);
343 Row = Obj.AssociatedObjectValue as Complex[];
344
345 if (Row is null)
346 {
347 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
348 "and return complex vectors of equal length. Type returned: " +
349 Obj.GetType().FullName, Node);
350 }
351 else if (Row.Length != c)
352 {
353 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
354 "and return complex vectors of equal length. Length returned: " +
355 Row.Length.ToString() + ". Expected: " + c.ToString(), Node);
356 }
357
358 for (x = x2 = 0; x < c; x++)
359 {
360 z = Row[x];
361 j = Offset[x];
362
363 Mod = z.Magnitude;
364
365 if (Mod < 3)
366 {
367 if (x != x2)
368 {
369 Row[x2] = z;
370 Row0[x2] = Row0[x];
371 Offset[x2] = j;
372 }
373
374 x2++;
375 }
376 else
377 {
378 if (n >= N)
379 ColorIndex[j++] = N;
380 else
381 ColorIndex[j++] = n;
382 }
383 }
384
385 if (x2 < x)
386 {
387 Array.Resize(ref Row, x2);
388 Array.Resize(ref Row0, x2);
389 Array.Resize(ref Offset, x2);
390 c = x2;
391 }
392 }
393
394 if (c > 0)
395 {
396 for (x = 0; x < c; x++)
397 {
398 j = Offset[x];
399 ColorIndex[j] = N;
400 }
401 }
402
403 }
404
405 Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
406
407 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
408 FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
409 FractalGraph.Diff(ColorIndex, Width, Height, out double[] dx, out double[] dy);
410 FractalGraph.Angle(ColorIndex, Width, Height, N, dx, dy);
411
412 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
413 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
414 }
415
419 public override string FunctionName => nameof(MandelbrotSmoothGradientFractal);
420
421 }
422}
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
Calculates a Mandelbrot Smooth Fractal Image, where coloring is done in accordance with the ange of t...
static FractalGraph CalcMandelbrot(double rCenter, double iCenter, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
MandelbrotSmoothGradientFractal(ScriptNode z, ScriptNode f, ScriptNode dr, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
MandelbrotSmoothGradientFractal(ScriptNode z, ScriptNode f, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
MandelbrotSmoothGradientFractal(ScriptNode z, ScriptNode f, ScriptNode dr, int Start, int Length, Expression Expression)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
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
MandelbrotSmoothGradientFractal(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 void Diff(double[] ColorIndex, int Width, int Height, out double[] dx, out double[] dy)
TODO
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
static void Angle(double[] ColorIndex, int Width, int Height, int N, double[] dx, double[] dy)
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