Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
NovaJuliaSmoothFractal.cs
1using System;
2using System.Numerics;
3using System.Text;
4using System.Threading.Tasks;
5using SkiaSharp;
12
14{
22 {
27 ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY,
29 : base(new ScriptNode[] { r, i, r0, i0, dr, R, p, Palette, DimX, DimY },
30 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
31 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
32 ArgumentType.Vector, ArgumentType.Scalar, ArgumentType.Scalar},
34 {
35 }
36
41 ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, int Start, int Length,
43 : base(new ScriptNode[] { r, i, r0, i0, dr, R, p, Palette, DimX },
44 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
45 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
46 ArgumentType.Vector, ArgumentType.Scalar },
48 {
49 }
50
56 : base(new ScriptNode[] { r, i, r0, i0, dr, R, p, Palette },
57 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
58 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
59 ArgumentType.Vector },
61 {
62 }
63
69 : base(new ScriptNode[] { r, i, r0, i0, dr, R, p },
70 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
71 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar },
73 {
74 }
75
79 public override string[] DefaultArgumentNames
80 {
81 get
82 {
83 return new string[] { "r", "i", "r0", "i0", "dr", "R", "p", "Palette", "DimX", "DimY" };
84 }
85 }
86
91 public override bool IsAsynchronous => true;
92
97 {
98 return this.EvaluateAsync(Arguments, Variables).Result;
99 }
100
104 public override async Task<IElement> EvaluateAsync(IElement[] Arguments, Variables Variables)
105 {
106 string ColorExpression = null;
107 SKColor[] Palette;
108 object Obj;
109 double rc, ic;
110 double r0, i0;
111 double dr;
112 double Rr, Ri, pr, pi;
113 int dimx, dimy;
114 int i, c;
115
116 rc = Expression.ToDouble(Arguments[0].AssociatedObjectValue);
117 ic = Expression.ToDouble(Arguments[1].AssociatedObjectValue);
118 r0 = Expression.ToDouble(Arguments[2].AssociatedObjectValue);
119 i0 = Expression.ToDouble(Arguments[3].AssociatedObjectValue);
120 dr = Expression.ToDouble(Arguments[4].AssociatedObjectValue);
121
122 if ((Obj = Arguments[5].AssociatedObjectValue) is Complex)
123 {
124 Complex z = (Complex)Obj;
125 Rr = z.Real;
126 Ri = z.Imaginary;
127 }
128 else
129 {
130 Rr = Expression.ToDouble(Arguments[5].AssociatedObjectValue);
131 Ri = 0;
132 }
133
134 if ((Obj = Arguments[6].AssociatedObjectValue) is Complex)
135 {
136 Complex z = (Complex)Obj;
137 pr = z.Real;
138 pi = z.Imaginary;
139 }
140 else
141 {
142 pr = Expression.ToDouble(Arguments[6].AssociatedObjectValue);
143 pi = 0;
144 }
145
146 c = Arguments.Length;
147 i = 7;
148
149 if (i < c && !(this.Arguments[i] is null) && Arguments[i] is ObjectVector)
150 {
151 ColorExpression = this.Arguments[i].SubExpression;
153 }
154 else
155 {
156 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(1024, 16, out int Seed, this, Variables);
157 ColorExpression = "RandomLinearAnalogousHSL(1024,16," + Seed.ToString() + ")";
158
159 if (i < c && this.Arguments[i] is null)
160 i++;
161 }
162
163 if (i < c)
164 dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
165 else
166 dimx = 320;
167
168 if (i < c)
169 dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
170 else
171 dimy = 200;
172
173 if (i < c)
174 {
175 throw new ScriptRuntimeException("Parameter mismatch in call to NovaJuliaSmoothFractal(r,c,r0,i0,dr,Coefficients[,Palette][,dimx[,dimy]]).",
176 this);
177 }
178
179 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
180 throw new FractalImageSizeScriptException(this);
181
182 return await CalcNovaJulia(rc, ic, r0, i0, dr, Rr, Ri, pr, pi, Palette, dimx, dimy,
183 this, Variables, this.FractalZoomScript,
184 new object[] { Palette, dimx, dimy, r0, i0, Rr, Ri, pr, pi, ColorExpression });
185 }
186
187 private string FractalZoomScript(double r, double i, double Size, object State)
188 {
189 object[] Parameters = (object[])State;
190 int DimX = (int)Parameters[1];
191 int DimY = (int)Parameters[2];
192 double r0 = (double)Parameters[3];
193 double i0 = (double)Parameters[4];
194 double Rr = (double)Parameters[5];
195 double Ri = (double)Parameters[6];
196 double pr = (double)Parameters[7];
197 double pi = (double)Parameters[8];
198 string ColorExpression = (string)Parameters[9];
199
200 StringBuilder sb = new StringBuilder();
201
202 sb.Append("NovaJuliaSmoothFractal(");
203 sb.Append(Expression.ToString(r));
204 sb.Append(',');
205 sb.Append(Expression.ToString(i));
206 sb.Append(',');
207 sb.Append(Expression.ToString(r0));
208 sb.Append(',');
209 sb.Append(Expression.ToString(i0));
210 sb.Append(',');
211 sb.Append(Expression.ToString(Size / 4));
212 sb.Append(',');
213 sb.Append(Expression.ToString(Rr));
214
215 if (Ri != 0)
216 {
217 sb.Append('+');
218 sb.Append(Expression.ToString(Ri));
219 sb.Append("*i");
220 }
221
222 sb.Append(',');
223 sb.Append(Expression.ToString(pr));
224
225 if (pi != 0)
226 {
227 sb.Append('+');
228 sb.Append(Expression.ToString(pi));
229 sb.Append("*i");
230 }
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 async Task<FractalGraph> CalcNovaJulia(double rCenter, double iCenter, double R0, double I0,
251 double rDelta, double Rr, double Ri, double pr, double pi, SKColor[] Palette,
252 int Width, int Height, ScriptNode Node, Variables Variables,
253 FractalZoomScript FractalZoomScript, object State)
254 {
255 double r0, i0, r1, i1;
256 double dr, di;
257 double r, i;
258 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
259 double aspect;
260 double Temp;
261 int x, y;
262 int n, N;
263 int index;
264 double lnz;
265 double argz;
266 double amp;
267 double phi;
268
269 N = Palette.Length;
270
271 int Size = Width * Height;
272 double[] ColorIndex = new double[Size];
273 double Conv = 1e-10;
274 double Div = 1e10;
275
276 rDelta *= 0.5;
277 r0 = rCenter - rDelta;
278 r1 = rCenter + rDelta;
279
280 aspect = ((double)Width) / Height;
281
282 i0 = iCenter - rDelta / aspect;
283 i1 = iCenter + rDelta / aspect;
284
285 dr = (r1 - r0) / Width;
286 di = (i1 - i0) / Height;
287
288 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
289 {
290 for (x = 0, r = r0; x < Width; x++, r += dr)
291 {
292 zr = r;
293 zi = i;
294
295 n = 0;
296 do
297 {
298 // f: z->z^p-1 = exp(p*ln(z))-1
299 // exp(a+ib)=exp(a)*(cos(b)+i*sin(b))
300 // ln(z)=ln|z|+i*arg(z)
301 // exp(p*ln(z))-1 =
302 // = exp((pr+i*pi)*(ln|z|+i*arg(z)))-1 =
303 // = exp(pr*ln|z|-pi*arg(z)+i*(pi*ln|z|+pr*arg(z)))-1 =
304 // = exp(pr*ln|z|-pi*arg(z))*(cos(pi*ln|z|+pr*arg(z))+i*sin(pi*ln|z|+pr*arg(z)))-1
305
306 lnz = Math.Log(Math.Sqrt(zr * zr + zi * zi));
307 argz = Math.Atan2(zi, zr);
308 amp = Math.Exp(pr * lnz - pi * argz);
309 phi = pi * lnz + pr * argz;
310
311 zr2 = amp * Math.Cos(phi) - 1;
312 zi2 = amp * Math.Sin(phi);
313
314 // f': z->p*z^(p-1) = p*exp((p-1)*ln(z)) =
315 // = (pr+i*pi)*exp((pr-1+i*pi)*(ln|z|+i*arg(z))) =
316 // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z)+i*(pi*ln|z|+(pr-1)*arg(z))) =
317 // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z))(sin(pi*ln|z|+(pr-1)*arg(z))+i*cos(pi*ln|z|+(pr-1)*arg(z))) =
318
319 amp = Math.Exp((pr - 1) * lnz - pi * argz);
320 phi = pi * lnz + (pr - 1) * argz;
321
322 zr3 = amp * Math.Cos(phi);
323 zi3 = amp * Math.Sin(phi);
324
325 Temp = pr * zr3 - pi * zi3;
326 zi3 = pr * zi3 + pi * zr3;
327 zr3 = Temp;
328
329 // f/f':
330
331 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
332 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
333 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
334
335 Temp = Rr * zr4 - Ri * zi4;
336 zi4 = Ri * zr4 + Rr * zi4 + I0;
337 zr4 = Temp + R0;
338
339 zr -= zr4;
340 zi -= zi4;
341
342 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
343 }
344 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
345
346 if (Temp < Conv && n < N)
347 ColorIndex[index++] = n;
348 else
349 ColorIndex[index++] = N;
350 }
351 }
352
353 await Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
354
355 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
356 await FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
357
358 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
359 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
360 }
361
365 public override string FunctionName => nameof(NovaJuliaSmoothFractal);
366 }
367}
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 Nova Julia Smooth Fractal Image (by Paul Derbyshire)
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
NovaJuliaSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode r0, ScriptNode i0, ScriptNode dr, ScriptNode R, ScriptNode p, int Start, int Length, Expression Expression)
TODO
static async Task< FractalGraph > CalcNovaJulia(double rCenter, double iCenter, double R0, double I0, double rDelta, double Rr, double Ri, double pr, double pi, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
NovaJuliaSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode r0, ScriptNode i0, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
NovaJuliaSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode r0, ScriptNode i0, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
NovaJuliaSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode r0, ScriptNode i0, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
Exception thrown if an image with invalid size is requested.
Defines a clickable fractal graph in the complex plane.
Definition: FractalGraph.cs:23
static async Task Smooth(double[] ColorIndex, double[] Boundary, int Width, int Height, int N, SKColor[] Palette, ScriptNode Node, Variables Variables)
TODO
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
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
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
async Task Preview(Expression Expression, IElement Result)
Reports a preview of the final result.
Definition: Variables.cs:407
Basic interface for all types of elements.
Definition: IElement.cs:21
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