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;
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;
102 ScriptNode fDef = null;
103 object Obj;
104
105 c = Arguments.Length;
106 i = 0;
107
108 Obj = Arguments[i++].AssociatedObjectValue;
109 if (Obj is Complex z)
110 {
111 z = (Complex)Obj;
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 JuliaTopographyFractal().", 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 JuliaTopographyFractal() 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 JuliaTopographyFractal().", 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 JuliaTopographyFractal().", 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(1024, 16, out int Seed, this, Variables);
161 ColorExpression = "RandomLinearAnalogousHSL(1024,16," + 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 JuliaTopographyFractal(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, dr, Variables, Palette, dimx, dimy, this,
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("JuliaTopographyFractal((");
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 double r0, i0, r1, i1;
252 double dr, di;
253 double r, i;
254 double zr, zi, zrt, zr2, zi2;
255 double aspect;
256 int x, y;
257 int n, N;
258 int index;
259
260 N = Palette.Length;
261
262 rDelta *= 0.5;
263 r0 = rCenter - rDelta;
264 r1 = rCenter + rDelta;
265
266 aspect = ((double)Width) / Height;
267
268 i0 = iCenter - rDelta / aspect;
269 i1 = iCenter + rDelta / aspect;
270
271 dr = (r1 - r0) / Width;
272 di = (i1 - i0) / Height;
273
274 int Size = Width * Height;
275 int[] ColorIndex = new int[Size];
276
277 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
278 {
279 for (x = 0, r = r0; x < Width; x++, r += dr)
280 {
281 zr = r;
282 zi = i;
283
284 n = 0;
285 zr2 = zr * zr;
286 zi2 = zi * zi;
287
288 while (zr2 + zi2 < 9 && n < N)
289 {
290 n++;
291 zrt = zr2 - zi2 + R0;
292 zi = 2 * zr * zi + I0;
293 zr = zrt;
294
295 zr2 = zr * zr;
296 zi2 = zi * zi;
297 }
298
299 if (n >= N)
300 ColorIndex[index++]=N;
301 else
302 ColorIndex[index++]=n;
303 }
304 }
305
306 int[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
307
308 return new FractalGraph(Variables, FractalGraph.ToPixels(Boundary, Width, Height, Palette),
309 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
310 }
311
315 public static FractalGraph CalcJulia(double rCenter, double iCenter, ILambdaExpression f,
316 double rDelta, Variables Variables, SKColor[] Palette, int Width, int Height, ScriptNode Node,
317 FractalZoomScript FractalZoomScript, object State)
318 {
319 double r0, i0, r1, i1;
320 double dr, di;
321 double r, i;
322 double aspect;
323 int x, y;
324 int n, N;
325
326 N = Palette.Length;
327
328 rDelta *= 0.5;
329 r0 = rCenter - rDelta;
330 r1 = rCenter + rDelta;
331
332 aspect = ((double)Width) / Height;
333
334 i0 = iCenter - rDelta / aspect;
335 i1 = iCenter + rDelta / aspect;
336
337 dr = (r1 - r0) / Width;
338 di = (i1 - i0) / Height;
339
340 int Size = Width * Height;
341 int[] ColorIndex = new int[Size];
342 int c, j, x2;
343 Complex z;
344 IElement[] P = new IElement[1];
345 IElement Obj;
346 double Mod;
347
348 for (y = 0, i = i0; y < Height; y++, i += di)
349 {
350 Complex[] Row = new Complex[Width];
351 int[] Offset = new int[Width];
352
353 c = Width;
354 for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++)
355 {
356 Row[x] = new Complex(r, i);
357 Offset[x] = x2;
358 }
359
360 Variables v = new Variables();
361 Variables.CopyTo(v);
362
363 n = 0;
364 while (n < N && c > 0)
365 {
366 n++;
367 P[0] = new ComplexVector(Row);
368 Obj = f.Evaluate(P, v);
369 Row = Obj.AssociatedObjectValue as Complex[];
370
371 if (Row is null)
372 throw new LambdaTypeScriptException(Obj.GetType(), Node);
373 else if (Row.Length != c)
374 throw new LambdaLengthScriptException(Row.Length, c, Node);
375
376 for (x = x2 = 0; x < c; x++)
377 {
378 z = Row[x];
379 j = Offset[x];
380
381 Mod = z.Magnitude;
382
383 if (Mod < 3)
384 {
385 if (x != x2)
386 {
387 Row[x2] = z;
388 Offset[x2] = j;
389 }
390
391 x2++;
392 }
393 else
394 ColorIndex[j++] = n;
395 }
396
397 if (x2 < x)
398 {
399 Array.Resize(ref Row, x2);
400 Array.Resize(ref Offset, x2);
401 c = x2;
402 }
403 }
404
405 if (c > 0)
406 {
407 for (x = 0; x < c; x++)
408 {
409 j = Offset[x];
410 ColorIndex[j] = N;
411 }
412 }
413 }
414
415 int[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
416
417 return new FractalGraph(Variables, FractalGraph.ToPixels(Boundary, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2,
418 true, Node, FractalZoomScript, State);
419 }
420
424 public override string FunctionName => nameof(JuliaTopographyFractal);
425 }
426}
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
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
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 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: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.
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