Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
JuliaSmoothFractal.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 JuliaSmoothFractal().", 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 JuliaSmoothFractal() 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 JuliaSmoothFractal().", 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 JuliaSmoothFractal().", this);
150
151 dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
152
153 c = Arguments.Length;
154
155 if (i < c && !(this.Arguments[i] is null) && Arguments[i] is ObjectVector)
156 {
157 ColorExpression = this.Arguments[i].SubExpression;
159 }
160 else
161 {
162 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(1024, 16, out int Seed, this, Variables);
163 ColorExpression = "RandomLinearAnalogousHSL(1024,16," + Seed.ToString() + ")";
164
165 if (i < c && this.Arguments[i] is null)
166 i++;
167 }
168
169 if (i < c)
170 dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
171 else
172 dimx = 320;
173
174 if (i < c)
175 dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
176 else
177 dimy = 200;
178
179 if (i < c)
180 {
181 throw new ScriptRuntimeException("Parameter mismatch in call to JuliaSmoothFractal(z,c|f,dr[,Palette][,dimx[,dimy]]).",
182 this);
183 }
184
185 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
186 throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
187
188 if (!(f is null))
189 {
190 return CalcJulia(rc, ic, f, dr, Palette, dimx, dimy, this, Variables,
191 this.FractalZoomScript, new object[] { Palette, dimx, dimy, r0, i0, ColorExpression, fDef });
192 }
193 else
194 {
195 return CalcJulia(rc, ic, r0, i0, dr, Palette, dimx, dimy, this, Variables,
196 this.FractalZoomScript, new object[] { Palette, dimx, dimy, r0, i0, ColorExpression, fDef });
197 }
198 }
199
200 private string FractalZoomScript(double r, double i, double Size, object State)
201 {
202 object[] Parameters = (object[])State;
203 int DimX = (int)Parameters[1];
204 int DimY = (int)Parameters[2];
205 double r0 = (double)Parameters[3];
206 double i0 = (double)Parameters[4];
207 string ColorExpression = (string)Parameters[5];
208 ScriptNode f = (ScriptNode)Parameters[6];
209
210 StringBuilder sb = new StringBuilder();
211
212 sb.Append("JuliaSmoothFractal((");
213 sb.Append(Expression.ToString(r));
214 sb.Append(',');
215 sb.Append(Expression.ToString(i));
216 sb.Append("),");
217
218 if (!(f is null))
219 sb.Append(f.SubExpression);
220 else
221 {
222 sb.Append('(');
223 sb.Append(Expression.ToString(r0));
224 sb.Append(',');
225 sb.Append(Expression.ToString(i0));
226 sb.Append(')');
227 }
228
229 sb.Append(',');
230 sb.Append(Expression.ToString(Size / 4));
231
232 if (!string.IsNullOrEmpty(ColorExpression))
233 {
234 sb.Append(',');
235 sb.Append(ColorExpression);
236 }
237
238 sb.Append(',');
239 sb.Append(DimX.ToString());
240 sb.Append(',');
241 sb.Append(DimY.ToString());
242 sb.Append(')');
243
244 return sb.ToString();
245 }
246
250 public static FractalGraph CalcJulia(double rCenter, double iCenter, double R0, double I0, double rDelta,
251 SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables,
252 FractalZoomScript FractalZoomScript, object State)
253 {
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
263 N = Palette.Length;
264
265 rDelta *= 0.5;
266 r0 = rCenter - rDelta;
267 r1 = rCenter + rDelta;
268
269 aspect = ((double)Width) / Height;
270
271 i0 = iCenter - rDelta / aspect;
272 i1 = iCenter + rDelta / aspect;
273
274 dr = (r1 - r0) / Width;
275 di = (i1 - i0) / Height;
276
277 int Size = Width * Height;
278 double[] ColorIndex = new double[Size];
279
280 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
281 {
282 for (x = 0, r = r0; x < Width; x++, r += dr)
283 {
284 zr = r;
285 zi = i;
286
287 n = 0;
288 zr2 = zr * zr;
289 zi2 = zi * zi;
290
291 while (zr2 + zi2 < 9 && n < N)
292 {
293 n++;
294 zrt = zr2 - zi2 + R0;
295 zi = 2 * zr * zi + I0;
296 zr = zrt;
297
298 zr2 = zr * zr;
299 zi2 = zi * zi;
300 }
301
302 if (n >= N)
303 ColorIndex[index++]=N;
304 else
305 ColorIndex[index++]=n;
306 }
307 }
308
309 Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
310
311 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
312 FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
313
314 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
315 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
316 }
317
321 public static FractalGraph CalcJulia(double rCenter, double iCenter, ILambdaExpression f,
322 double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node,
323 Variables Variables, FractalZoomScript FractalZoomScript, object State)
324 {
325 double r0, i0, r1, i1;
326 double dr, di;
327 double r, i;
328 double aspect;
329 int x, y;
330 int n, N;
331
332 N = Palette.Length;
333
334 rDelta *= 0.5;
335 r0 = rCenter - rDelta;
336 r1 = rCenter + rDelta;
337
338 aspect = ((double)Width) / Height;
339
340 i0 = iCenter - rDelta / aspect;
341 i1 = iCenter + rDelta / aspect;
342
343 dr = (r1 - r0) / Width;
344 di = (i1 - i0) / Height;
345
346 int Size = Width * Height;
347 double[] ColorIndex = new double[Size];
348 int c, j, x2;
349 Complex z;
350 IElement[] P = new IElement[1];
351 IElement Obj;
352 double Mod;
353
354 for (y = 0, i = i0; y < Height; y++, i += di)
355 {
356 Complex[] Row = new Complex[Width];
357 int[] Offset = new int[Width];
358
359 c = Width;
360 for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++)
361 {
362 Row[x] = new Complex(r, i);
363 Offset[x] = x2;
364 }
365
366 n = 0;
367 while (n < N && c > 0)
368 {
369 n++;
370 P[0] = new ComplexVector(Row);
371 Obj = f.Evaluate(P, Variables);
372 Row = Obj.AssociatedObjectValue as Complex[];
373
374 if (Row is null)
375 {
376 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
377 "and return complex vectors of equal length. Type returned: " +
378 Obj.GetType().FullName, Node);
379 }
380 else if (Row.Length != c)
381 {
382 throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " +
383 "and return complex vectors of equal length. Length returned: " +
384 Row.Length.ToString() + ". Expected: " + c.ToString(), Node);
385 }
386
387 for (x = x2 = 0; x < c; x++)
388 {
389 z = Row[x];
390 j = Offset[x];
391
392 Mod = z.Magnitude;
393
394 if (Mod < 3)
395 {
396 if (x != x2)
397 {
398 Row[x2] = z;
399 Offset[x2] = j;
400 }
401
402 x2++;
403 }
404 else
405 ColorIndex[j++] = n;
406 }
407
408 if (x2 < x)
409 {
410 Array.Resize(ref Row, x2);
411 Array.Resize(ref Offset, x2);
412 c = x2;
413 }
414 }
415
416 if (c > 0)
417 {
418 for (x = 0; x < c; x++)
419 {
420 j = Offset[x];
421 ColorIndex[j] = N;
422 }
423 }
424 }
425
426 Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
427
428 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
429 FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
430
431 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
432 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
433 }
434
438 public override string FunctionName => nameof(JuliaSmoothFractal);
439 }
440}
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
JuliaSmoothFractal(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, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
static FractalGraph CalcJulia(double rCenter, double iCenter, double R0, double I0, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
JuliaSmoothFractal(ScriptNode z, ScriptNode c, ScriptNode dr, int Start, int Length, Expression Expression)
TODO
JuliaSmoothFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
JuliaSmoothFractal(ScriptNode z, ScriptNode c, ScriptNode dr, ScriptNode Palette, int Start, int Length, Expression Expression)
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
static void Smooth(double[] ColorIndex, double[] Boundary, int Width, int Height, int N, SKColor[] Palette, ScriptNode Node, Variables Variables)
TODO
Handles bitmap-based graphs.
Definition: GraphBitmap.cs:13
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 Preview(Expression Expression, IElement Result)
Reports a preview of the final result.
Definition: Variables.cs:455
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