Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
JuliaSmoothFractal.cs
1using System;
2using System.Numerics;
3using System.Text;
4using System.Threading.Tasks;
5using SkiaSharp;
12
14{
38 {
44 : base(new ScriptNode[] { z, c, dr, Palette, DimX, DimY },
45 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
47 {
48 }
49
55 : base(new ScriptNode[] { z, c, dr, Palette, DimX },
56 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
58 {
59 }
60
65 : base(new ScriptNode[] { z, c, dr, Palette },
66 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
68 {
69 }
70
75 : base(new ScriptNode[] { z, c, dr },
76 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar }, Start, Length, Expression)
77 {
78 }
79
83 public override string[] DefaultArgumentNames
84 {
85 get
86 {
87 return new string[] { "z", "c", "dr", "Palette", "DimX", "DimY" };
88 }
89 }
90
95 public override bool IsAsynchronous => true;
96
101 {
102 return this.EvaluateAsync(Arguments, Variables).Result;
103 }
104
108 public override async Task<IElement> EvaluateAsync(IElement[] Arguments, Variables Variables)
109 {
110 string ColorExpression = null;
111 SKColor[] Palette;
112 double rc, ic;
113 double r0, i0;
114 double dr;
115 int dimx, dimy;
116 int i, c;
118 ScriptNode fDef = null;
119 object Obj;
120
121 c = Arguments.Length;
122 i = 0;
123
124 Obj = Arguments[i++].AssociatedObjectValue;
125 if (Obj is Complex z)
126 {
127 z = (Complex)Obj;
128 rc = z.Real;
129 ic = z.Imaginary;
130 }
131 else
132 {
133 rc = Expression.ToDouble(Obj);
134 ic = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
135 }
136
137 if (i >= c)
138 throw new ScriptRuntimeException("Insufficient parameters in call to JuliaSmoothFractal().", this);
139
140 Obj = Arguments[i++].AssociatedObjectValue;
141 if (!((f = Obj as ILambdaExpression) is null))
142 {
143 if (f.NrArguments != 1)
144 throw new ScriptRuntimeException("Lambda expression in calls to JuliaSmoothFractal() must be of one variable.", this);
145
146 r0 = 0;
147 i0 = 0;
148 fDef = this.Arguments[i - 1];
149 }
150 else if (Obj is Complex z2)
151 {
152 r0 = z2.Real;
153 i0 = z2.Imaginary;
154 }
155 else
156 {
157 if (i >= c)
158 throw new ScriptRuntimeException("Insufficient parameters in call to JuliaSmoothFractal().", this);
159
160 r0 = Expression.ToDouble(Obj);
161 i0 = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
162 }
163
164 if (i >= c)
165 throw new ScriptRuntimeException("Insufficient parameters in call to JuliaSmoothFractal().", this);
166
167 dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
168
169 c = Arguments.Length;
170
171 if (i < c && !(this.Arguments[i] is null) && Arguments[i] is ObjectVector)
172 {
173 ColorExpression = this.Arguments[i].SubExpression;
175 }
176 else
177 {
178 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(1024, 16, out int Seed, this, Variables);
179 ColorExpression = "RandomLinearAnalogousHSL(1024,16," + Seed.ToString() + ")";
180
181 if (i < c && this.Arguments[i] is null)
182 i++;
183 }
184
185 if (i < c)
186 dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
187 else
188 dimx = 320;
189
190 if (i < c)
191 dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
192 else
193 dimy = 200;
194
195 if (i < c)
196 {
197 throw new ScriptRuntimeException("Parameter mismatch in call to JuliaSmoothFractal(z,c|f,dr[,Palette][,dimx[,dimy]]).",
198 this);
199 }
200
201 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
202 throw new FractalImageSizeScriptException(this);
203
204 if (!(f is null))
205 {
206 return await CalcJulia(rc, ic, f, dr, Palette, dimx, dimy, this, Variables,
207 this.FractalZoomScript, new object[] { Palette, dimx, dimy, r0, i0, ColorExpression, fDef });
208 }
209 else
210 {
211 return await CalcJulia(rc, ic, r0, i0, dr, Palette, dimx, dimy, this, Variables,
212 this.FractalZoomScript, new object[] { Palette, dimx, dimy, r0, i0, ColorExpression, fDef });
213 }
214 }
215
216 private string FractalZoomScript(double r, double i, double Size, object State)
217 {
218 object[] Parameters = (object[])State;
219 int DimX = (int)Parameters[1];
220 int DimY = (int)Parameters[2];
221 double r0 = (double)Parameters[3];
222 double i0 = (double)Parameters[4];
223 string ColorExpression = (string)Parameters[5];
224 ScriptNode f = (ScriptNode)Parameters[6];
225
226 StringBuilder sb = new StringBuilder();
227
228 sb.Append("JuliaSmoothFractal((");
229 sb.Append(Expression.ToString(r));
230 sb.Append(',');
231 sb.Append(Expression.ToString(i));
232 sb.Append("),");
233
234 if (!(f is null))
235 sb.Append(f.SubExpression);
236 else
237 {
238 sb.Append('(');
239 sb.Append(Expression.ToString(r0));
240 sb.Append(',');
241 sb.Append(Expression.ToString(i0));
242 sb.Append(')');
243 }
244
245 sb.Append(',');
246 sb.Append(Expression.ToString(Size / 4));
247
248 if (!string.IsNullOrEmpty(ColorExpression))
249 {
250 sb.Append(',');
251 sb.Append(ColorExpression);
252 }
253
254 sb.Append(',');
255 sb.Append(DimX.ToString());
256 sb.Append(',');
257 sb.Append(DimY.ToString());
258 sb.Append(')');
259
260 return sb.ToString();
261 }
262
266 public static async Task<FractalGraph> CalcJulia(double rCenter, double iCenter, double R0, double I0, double rDelta,
267 SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables,
268 FractalZoomScript FractalZoomScript, object State)
269 {
270 double r0, i0, r1, i1;
271 double dr, di;
272 double r, i;
273 double zr, zi, zrt, zr2, zi2;
274 double aspect;
275 int x, y;
276 int n, N;
277 int index;
278
279 N = Palette.Length;
280
281 rDelta *= 0.5;
282 r0 = rCenter - rDelta;
283 r1 = rCenter + rDelta;
284
285 aspect = ((double)Width) / Height;
286
287 i0 = iCenter - rDelta / aspect;
288 i1 = iCenter + rDelta / aspect;
289
290 dr = (r1 - r0) / Width;
291 di = (i1 - i0) / Height;
292
293 int Size = Width * Height;
294 double[] ColorIndex = new double[Size];
295
296 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
297 {
298 for (x = 0, r = r0; x < Width; x++, r += dr)
299 {
300 zr = r;
301 zi = i;
302
303 n = 0;
304 zr2 = zr * zr;
305 zi2 = zi * zi;
306
307 while (zr2 + zi2 < 9 && n < N)
308 {
309 n++;
310 zrt = zr2 - zi2 + R0;
311 zi = 2 * zr * zi + I0;
312 zr = zrt;
313
314 zr2 = zr * zr;
315 zi2 = zi * zi;
316 }
317
318 if (n >= N)
319 ColorIndex[index++]=N;
320 else
321 ColorIndex[index++]=n;
322 }
323 }
324
325 await Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
326
327 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
328 await FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
329
330 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
331 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
332 }
333
337 public static async Task<FractalGraph> CalcJulia(double rCenter, double iCenter, ILambdaExpression f,
338 double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node,
339 Variables Variables, FractalZoomScript FractalZoomScript, object State)
340 {
341 double r0, i0, r1, i1;
342 double dr, di;
343 double r, i;
344 double aspect;
345 int x, y;
346 int n, N;
347
348 N = Palette.Length;
349
350 rDelta *= 0.5;
351 r0 = rCenter - rDelta;
352 r1 = rCenter + rDelta;
353
354 aspect = ((double)Width) / Height;
355
356 i0 = iCenter - rDelta / aspect;
357 i1 = iCenter + rDelta / aspect;
358
359 dr = (r1 - r0) / Width;
360 di = (i1 - i0) / Height;
361
362 int Size = Width * Height;
363 double[] ColorIndex = new double[Size];
364 int c, j, x2;
365 Complex z;
366 IElement[] P = new IElement[1];
367 IElement Obj;
368 double Mod;
369
370 for (y = 0, i = i0; y < Height; y++, i += di)
371 {
372 Complex[] Row = new Complex[Width];
373 int[] Offset = new int[Width];
374
375 c = Width;
376 for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++)
377 {
378 Row[x] = new Complex(r, i);
379 Offset[x] = x2;
380 }
381
382 n = 0;
383 while (n < N && c > 0)
384 {
385 n++;
386 P[0] = new ComplexVector(Row);
387 Obj = f.Evaluate(P, Variables);
388 Row = Obj.AssociatedObjectValue as Complex[];
389
390 if (Row is null)
391 throw new LambdaTypeScriptException(Obj.GetType(), Node);
392 else if (Row.Length != c)
393 throw new LambdaLengthScriptException(Row.Length, c, Node);
394
395 for (x = x2 = 0; x < c; x++)
396 {
397 z = Row[x];
398 j = Offset[x];
399
400 Mod = z.Magnitude;
401
402 if (Mod < 3)
403 {
404 if (x != x2)
405 {
406 Row[x2] = z;
407 Offset[x2] = j;
408 }
409
410 x2++;
411 }
412 else
413 ColorIndex[j++] = n;
414 }
415
416 if (x2 < x)
417 {
418 Array.Resize(ref Row, x2);
419 Array.Resize(ref Offset, x2);
420 c = x2;
421 }
422 }
423
424 if (c > 0)
425 {
426 for (x = 0; x < c; x++)
427 {
428 j = Offset[x];
429 ColorIndex[j] = N;
430 }
431 }
432 }
433
434 await Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
435
436 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
437 await FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
438
439 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
440 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
441 }
442
446 public override string FunctionName => nameof(JuliaSmoothFractal);
447 }
448}
Class managing a script expression.
Definition: Expression.cs:41
static double ToDouble(object Object)
Converts an object to a double value.
Definition: Expression.cs:5110
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Definition: Expression.cs:4760
JuliaSmoothFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
JuliaSmoothFractal(ScriptNode z, ScriptNode c, ScriptNode dr, int Start, int Length, Expression Expression)
TODO
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
TODO
JuliaSmoothFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
JuliaSmoothFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
static async Task< FractalGraph > CalcJulia(double rCenter, double iCenter, ILambdaExpression f, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
static async Task< FractalGraph > CalcJulia(double rCenter, double iCenter, double R0, double I0, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
Exception thrown if an image with invalid size is requested.
Exception thrown if a lambda expression with invalid type is encountered.
Exception thrown if a lambda expression with invalid type is encountered.
Defines a clickable fractal graph in the complex plane.
Definition: FractalGraph.cs:23
static async Task Smooth(double[] ColorIndex, double[] Boundary, int Width, int Height, int N, SKColor[] Palette, ScriptNode Node, Variables Variables)
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
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
async Task Preview(Expression Expression, IElement Result)
Reports a preview of the final result.
Definition: Variables.cs:407
Basic interface for all types of elements.
Definition: IElement.cs:21
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