Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
JuliaFractal.cs
1using System;
2using System.Numerics;
3using System.Text;
4using SkiaSharp;
10
12{
36 {
42 : base(new ScriptNode[] { z, c, dr, Palette, DimX, DimY },
43 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
45 {
46 }
47
53 : base(new ScriptNode[] { z, c, dr, Palette, DimX },
54 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
56 {
57 }
58
63 : base(new ScriptNode[] { z, c, dr, Palette },
64 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
66 {
67 }
68
73 : base(new ScriptNode[] { z, c, dr },
74 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar }, Start, Length, Expression)
75 {
76 }
77
81 public override string[] DefaultArgumentNames
82 {
83 get
84 {
85 return new string[] { "z", "c", "dr", "Palette", "DimX", "DimY" };
86 }
87 }
88
93 {
94 string ColorExpression = null;
95 SKColor[] Palette;
96 double rc, ic;
97 double r0, i0;
98 double dr;
99 int dimx, dimy;
100 int i, c;
101 object Obj;
103 ScriptNode fDef = null;
104 c = Arguments.Length;
105 i = 0;
106
107 Obj = Arguments[i++].AssociatedObjectValue;
108 if (Obj is Complex z)
109 {
110 rc = z.Real;
111 ic = z.Imaginary;
112 }
113 else
114 {
115 rc = Expression.ToDouble(Obj);
116 ic = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
117 }
118
119 if (i >= c)
120 throw new ScriptRuntimeException("Insufficient parameters in call to JuliaFractal().", this);
121
122 Obj = Arguments[i++].AssociatedObjectValue;
123 if (!((f = Obj as ILambdaExpression) is null))
124 {
125 if (f.NrArguments != 1)
126 throw new ScriptRuntimeException("Lambda expression in calls to JuliaFractal() must be of one variable.", this);
127
128 r0 = 0;
129 i0 = 0;
130 fDef = this.Arguments[i - 1];
131 }
132 else if (Obj is Complex z2)
133 {
134 r0 = z2.Real;
135 i0 = z2.Imaginary;
136 }
137 else
138 {
139 if (i >= c)
140 throw new ScriptRuntimeException("Insufficient parameters in call to JuliaFractal().", this);
141
142 r0 = Expression.ToDouble(Obj);
143 i0 = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
144 }
145
146 if (i >= c)
147 throw new ScriptRuntimeException("Insufficient parameters in call to JuliaFractal().", this);
148
149 dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
150
151 if (i < c && !(this.Arguments[i] is null) && Arguments[i] is ObjectVector)
152 {
153 ColorExpression = this.Arguments[i].SubExpression;
155 }
156 else
157 {
158 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(1024, 16, out int Seed, this, Variables);
159 ColorExpression = "RandomLinearAnalogousHSL(1024,16," + Seed.ToString() + ")";
160
161 if (i < c && this.Arguments[i] is null)
162 i++;
163 }
164
165 if (i < c)
166 dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
167 else
168 dimx = 320;
169
170 if (i < c)
171 dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
172 else
173 dimy = 200;
174
175 if (i < c)
176 {
177 throw new ScriptRuntimeException("Parameter mismatch in call to JuliaFractal(z,c|f,dr[,Palette][,dimx[,dimy]]).",
178 this);
179 }
180
181 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
182 throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
183
184 if (!(f is null))
185 {
186 return CalcJulia(rc, ic, f, fDef, dr, Palette, dimx, dimy, this, Variables,
187 this.FractalZoomScript, new object[] { Palette, dimx, dimy, r0, i0, ColorExpression, fDef });
188 }
189 else
190 {
191 return CalcJulia(Variables, rc, ic, r0, i0, dr, Palette, dimx, dimy, this,
192 this.FractalZoomScript, new object[] { Palette, dimx, dimy, r0, i0, ColorExpression, fDef });
193 }
194 }
195
196 private string FractalZoomScript(double r, double i, double Size, object State)
197 {
198 object[] Parameters = (object[])State;
199 int DimX = (int)Parameters[1];
200 int DimY = (int)Parameters[2];
201 double r0 = (double)Parameters[3];
202 double i0 = (double)Parameters[4];
203 string ColorExpression = (string)Parameters[5];
204 ScriptNode f = (ScriptNode)Parameters[6];
205
206 StringBuilder sb = new StringBuilder();
207
208 sb.Append("JuliaFractal((");
209 sb.Append(Expression.ToString(r));
210 sb.Append(',');
211 sb.Append(Expression.ToString(i));
212 sb.Append("),");
213
214 if (!(f is null))
215 sb.Append(f.SubExpression);
216 else
217 {
218 sb.Append('(');
219 sb.Append(Expression.ToString(r0));
220 sb.Append(',');
221 sb.Append(Expression.ToString(i0));
222 sb.Append(')');
223 }
224
225 sb.Append(',');
226 sb.Append(Expression.ToString(Size / 4));
227
228 if (!string.IsNullOrEmpty(ColorExpression))
229 {
230 sb.Append(',');
231 sb.Append(ColorExpression);
232 }
233
234 sb.Append(',');
235 sb.Append(DimX.ToString());
236 sb.Append(',');
237 sb.Append(DimY.ToString());
238 sb.Append(')');
239
240 return sb.ToString();
241 }
242
246 public static FractalGraph CalcJulia(Variables Variables, double rCenter, double iCenter, double R0, double I0, double rDelta,
247 SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
248 {
249 byte[] reds;
250 byte[] greens;
251 byte[] blues;
252 double r0, i0, r1, i1;
253 double dr, di;
254 double r, i;
255 double zr, zi, zrt, zr2, zi2;
256 double aspect;
257 int x, y;
258 int n, N;
259 int index;
260 SKColor cl;
261
262 N = Palette.Length;
263 reds = new byte[N];
264 greens = new byte[N];
265 blues = new byte[N];
266
267 for (x = 0; x < N; x++)
268 {
269 cl = Palette[x];
270 reds[x] = cl.Red;
271 greens[x] = cl.Green;
272 blues[x] = cl.Blue;
273 }
274
275 int size = Width * Height * 4;
276 byte[] rgb = new byte[size];
277
278 rDelta *= 0.5;
279 r0 = rCenter - rDelta;
280 r1 = rCenter + rDelta;
281
282 aspect = ((double)Width) / Height;
283
284 i0 = iCenter - rDelta / aspect;
285 i1 = iCenter + rDelta / aspect;
286
287 dr = (r1 - r0) / Width;
288 di = (i1 - i0) / Height;
289
290 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
291 {
292 for (x = 0, r = r0; x < Width; x++, r += dr)
293 {
294 zr = r;
295 zi = i;
296
297 n = 0;
298 zr2 = zr * zr;
299 zi2 = zi * zi;
300
301 while (zr2 + zi2 < 9 && n < N)
302 {
303 n++;
304 zrt = zr2 - zi2 + R0;
305 zi = 2 * zr * zi + I0;
306 zr = zrt;
307
308 zr2 = zr * zr;
309 zi2 = zi * zi;
310 }
311
312 if (n >= N)
313 {
314 rgb[index++] = 0;
315 rgb[index++] = 0;
316 rgb[index++] = 0;
317 }
318 else
319 {
320 rgb[index++] = blues[n];
321 rgb[index++] = greens[n];
322 rgb[index++] = reds[n];
323 }
324
325 rgb[index++] = 255;
326 }
327 }
328
329 PixelInformation Pixels = new PixelInformationRaw(SKColorType.Bgra8888, rgb, Width, Height, Width << 2);
330 return new FractalGraph(Variables, Pixels, r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
331 }
332
336 public static FractalGraph CalcJulia(double rCenter, double iCenter, ILambdaExpression f, ScriptNode _,
337 double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables,
338 FractalZoomScript FractalZoomScript, object State)
339 {
340 byte[] reds;
341 byte[] greens;
342 byte[] blues;
343 double r0, i0, r1, i1;
344 double dr, di;
345 double r, i, Mod;
346 double aspect;
347 int x, x2, y;
348 int n, N;
349 SKColor cl;
350
351 N = Palette.Length;
352 reds = new byte[N];
353 greens = new byte[N];
354 blues = new byte[N];
355
356 for (x = 0; x < N; x++)
357 {
358 cl = Palette[x];
359 reds[x] = cl.Red;
360 greens[x] = cl.Green;
361 blues[x] = cl.Blue;
362 }
363
364 int size = Width * Height * 4;
365 byte[] rgb = new byte[size];
366 Complex z;
367 IElement[] P = new IElement[1];
368 int j, c;
369 IElement Obj;
370
371 rDelta *= 0.5;
372 r0 = rCenter - rDelta;
373 r1 = rCenter + rDelta;
374
375 aspect = ((double)Width) / Height;
376
377 i0 = iCenter - rDelta / aspect;
378 i1 = iCenter + rDelta / aspect;
379
380 dr = (r1 - r0) / Width;
381 di = (i1 - i0) / Height;
382
383 for (y = 0, i = i0; y < Height; y++, i += di)
384 {
385 Complex[] Row = new Complex[Width];
386 int[] Offset = new int[Width];
387
388 c = Width;
389 for (x = 0, x2 = y * Width * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
390 {
391 Row[x] = new Complex(r, i);
392 Offset[x] = x2;
393 }
394
395 Variables v = new Variables();
396 Variables.CopyTo(v);
397
398 n = 0;
399 while (n < N && c > 0)
400 {
401 n++;
402 P[0] = new ComplexVector(Row);
403 Obj = f.Evaluate(P, v);
404 Row = Obj.AssociatedObjectValue as Complex[];
405
406 if (Row is null)
407 {
408 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
409 "and return complex vectors of equal length. Type returned: " +
410 Obj.GetType().FullName, Node);
411 }
412 else if (Row.Length != c)
413 {
414 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
415 "and return complex vectors of equal length. Length returned: " +
416 Row.Length.ToString() + ". Expected: " + c.ToString(), Node);
417 }
418
419 for (x = x2 = 0; x < c; x++)
420 {
421 z = Row[x];
422 j = Offset[x];
423
424 Mod = z.Magnitude;
425
426 if (Mod < 3)
427 {
428 if (x != x2)
429 {
430 Row[x2] = z;
431 Offset[x2] = j;
432 }
433
434 x2++;
435 }
436 else
437 {
438 if (n >= N)
439 {
440 rgb[j++] = 0;
441 rgb[j++] = 0;
442 rgb[j++] = 0;
443 }
444 else
445 {
446 rgb[j++] = blues[n];
447 rgb[j++] = greens[n];
448 rgb[j++] = reds[n];
449 }
450
451 rgb[j++] = 255;
452 }
453 }
454
455 if (x2 < x)
456 {
457 Array.Resize(ref Row, x2);
458 Array.Resize(ref Offset, x2);
459 c = x2;
460 }
461 }
462
463 if (c > 0)
464 {
465 for (x = 0; x < c; x++)
466 {
467 j = Offset[x];
468
469 rgb[j++] = 0;
470 rgb[j++] = 0;
471 rgb[j++] = 0;
472 rgb[j++] = 255;
473 }
474 }
475
476 }
477
478 PixelInformation Pixels = new PixelInformationRaw(SKColorType.Bgra8888, rgb, Width, Height, Width << 2);
479 return new FractalGraph(Variables, Pixels, r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
480 }
481
485 public override string FunctionName => nameof(JuliaFractal);
486 }
487}
Class managing a script expression.
Definition: Expression.cs:39
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 Julia set Fractal Image
Definition: JuliaFractal.cs:36
static FractalGraph CalcJulia(double rCenter, double iCenter, ILambdaExpression f, ScriptNode _, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
static FractalGraph CalcJulia(Variables Variables, double rCenter, double iCenter, double R0, double I0, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
JuliaFractal(ScriptNode z, ScriptNode c, ScriptNode dr, int Start, int Length, Expression Expression)
TODO
Definition: JuliaFractal.cs:72
JuliaFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
Definition: JuliaFractal.cs:62
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
Definition: JuliaFractal.cs:92
JuliaFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
Definition: JuliaFractal.cs:40
JuliaFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
Definition: JuliaFractal.cs:51
Defines a clickable fractal graph in the complex plane.
Definition: FractalGraph.cs:22
static SKColor[] ToPalette(ObjectVector Vector)
TODO
Contains pixel information
Contains pixel information in a raw unencoded format.
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