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