Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
JuliaTopographyFractal.cs
1using System;
2using System.Numerics;
3using System.Text;
4using SkiaSharp;
9
11{
35 {
41 : base(new ScriptNode[] { z, c, dr, Palette, DimX, DimY },
42 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
44 {
45 }
46
52 : base(new ScriptNode[] { z, c, dr, Palette, DimX },
53 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
55 {
56 }
57
62 : base(new ScriptNode[] { z, c, dr, Palette },
63 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
65 {
66 }
67
72 : base(new ScriptNode[] { z, c, dr },
73 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar }, Start, Length, Expression)
74 {
75 }
76
80 public override string[] DefaultArgumentNames
81 {
82 get
83 {
84 return new string[] { "z", "c", "dr", "Palette", "DimX", "DimY" };
85 }
86 }
87
92 {
93 string ColorExpression = null;
94 SKColor[] Palette;
95 double rc, ic;
96 double r0, i0;
97 double dr;
98 int dimx, dimy;
99 int i, c;
101 ScriptNode fDef = null;
102 object Obj;
103
104 c = Arguments.Length;
105 i = 0;
106
107 Obj = Arguments[i++].AssociatedObjectValue;
108 if (Obj is Complex z)
109 {
110 z = (Complex)Obj;
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 JuliaTopographyFractal().", 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 JuliaTopographyFractal() 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 JuliaTopographyFractal().", 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 JuliaTopographyFractal().", 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 JuliaTopographyFractal(z,c|f,dr[,Palette][,dimx[,dimy]]).",
179 this);
180 }
181
182 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
183 throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
184
185 if (!(f is null))
186 {
187 return CalcJulia(rc, ic, f, dr, Variables, Palette, dimx, dimy, this,
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("JuliaTopographyFractal((");
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 double r0, i0, r1, i1;
251 double dr, di;
252 double r, i;
253 double zr, zi, zrt, zr2, zi2;
254 double aspect;
255 int x, y;
256 int n, N;
257 int index;
258
259 N = Palette.Length;
260
261 rDelta *= 0.5;
262 r0 = rCenter - rDelta;
263 r1 = rCenter + rDelta;
264
265 aspect = ((double)Width) / Height;
266
267 i0 = iCenter - rDelta / aspect;
268 i1 = iCenter + rDelta / aspect;
269
270 dr = (r1 - r0) / Width;
271 di = (i1 - i0) / Height;
272
273 int Size = Width * Height;
274 int[] ColorIndex = new int[Size];
275
276 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
277 {
278 for (x = 0, r = r0; x < Width; x++, r += dr)
279 {
280 zr = r;
281 zi = i;
282
283 n = 0;
284 zr2 = zr * zr;
285 zi2 = zi * zi;
286
287 while (zr2 + zi2 < 9 && n < N)
288 {
289 n++;
290 zrt = zr2 - zi2 + R0;
291 zi = 2 * zr * zi + I0;
292 zr = zrt;
293
294 zr2 = zr * zr;
295 zi2 = zi * zi;
296 }
297
298 if (n >= N)
299 ColorIndex[index++]=N;
300 else
301 ColorIndex[index++]=n;
302 }
303 }
304
305 int[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
306
307 return new FractalGraph(Variables, FractalGraph.ToPixels(Boundary, Width, Height, Palette),
308 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
309 }
310
314 public static FractalGraph CalcJulia(double rCenter, double iCenter, ILambdaExpression f,
315 double rDelta, Variables Variables, SKColor[] Palette, int Width, int Height, ScriptNode Node,
316 FractalZoomScript FractalZoomScript, object State)
317 {
318 double r0, i0, r1, i1;
319 double dr, di;
320 double r, i;
321 double aspect;
322 int x, y;
323 int n, N;
324
325 N = Palette.Length;
326
327 rDelta *= 0.5;
328 r0 = rCenter - rDelta;
329 r1 = rCenter + rDelta;
330
331 aspect = ((double)Width) / Height;
332
333 i0 = iCenter - rDelta / aspect;
334 i1 = iCenter + rDelta / aspect;
335
336 dr = (r1 - r0) / Width;
337 di = (i1 - i0) / Height;
338
339 int Size = Width * Height;
340 int[] ColorIndex = new int[Size];
341 int c, j, x2;
342 Complex z;
343 IElement[] P = new IElement[1];
344 IElement Obj;
345 double Mod;
346
347 for (y = 0, i = i0; y < Height; y++, i += di)
348 {
349 Complex[] Row = new Complex[Width];
350 int[] Offset = new int[Width];
351
352 c = Width;
353 for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++)
354 {
355 Row[x] = new Complex(r, i);
356 Offset[x] = x2;
357 }
358
359 Variables v = new Variables();
360 Variables.CopyTo(v);
361
362 n = 0;
363 while (n < N && c > 0)
364 {
365 n++;
366 P[0] = new ComplexVector(Row);
367 Obj = f.Evaluate(P, v);
368 Row = Obj.AssociatedObjectValue as Complex[];
369
370 if (Row is null)
371 {
372 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
373 "and return complex vectors of equal length. Type returned: " +
374 Obj.GetType().FullName, Node);
375 }
376 else if (Row.Length != c)
377 {
378 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
379 "and return complex vectors of equal length. Length returned: " +
380 Row.Length.ToString() + ". Expected: " + c.ToString(), Node);
381 }
382
383 for (x = x2 = 0; x < c; x++)
384 {
385 z = Row[x];
386 j = Offset[x];
387
388 Mod = z.Magnitude;
389
390 if (Mod < 3)
391 {
392 if (x != x2)
393 {
394 Row[x2] = z;
395 Offset[x2] = j;
396 }
397
398 x2++;
399 }
400 else
401 ColorIndex[j++] = n;
402 }
403
404 if (x2 < x)
405 {
406 Array.Resize(ref Row, x2);
407 Array.Resize(ref Offset, x2);
408 c = x2;
409 }
410 }
411
412 if (c > 0)
413 {
414 for (x = 0; x < c; x++)
415 {
416 j = Offset[x];
417 ColorIndex[j] = N;
418 }
419 }
420 }
421
422 int[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
423
424 return new FractalGraph(Variables, FractalGraph.ToPixels(Boundary, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2,
425 true, Node, FractalZoomScript, State);
426 }
427
431 public override string FunctionName => nameof(JuliaTopographyFractal);
432 }
433}
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
JuliaTopographyFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
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
JuliaTopographyFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
JuliaTopographyFractal(ScriptNode z, ScriptNode c, ScriptNode dr, int Start, int Length, Expression Expression)
TODO
JuliaTopographyFractal(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, double rDelta, Variables Variables, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
Defines a clickable fractal graph in the complex plane.
Definition: FractalGraph.cs:22
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
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