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