Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
NovaSmoothFractal.cs
1using System;
2using System.Numerics;
3using System.Text;
4using System.Threading.Tasks;
5using SkiaSharp;
12
14{
34 {
39 ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
40 : base(new ScriptNode[] { r, i, dr, R, p, Palette, DimX, DimY },
41 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
42 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Vector, ArgumentType.Scalar,
44 {
45 }
46
51 ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
52 : base(new ScriptNode[] { r, i, dr, R, p, Palette, DimX },
53 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
54 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Vector, ArgumentType.Scalar },
56 {
57 }
58
63 ScriptNode Palette, int Start, int Length, Expression Expression)
64 : base(new ScriptNode[] { r, i, dr, R, p, Palette },
65 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
66 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Vector },
68 {
69 }
70
76 : base(new ScriptNode[] { r, i, dr, R, p },
77 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
78 ArgumentType.Scalar, ArgumentType.Scalar },
80 {
81 }
82
86 public override string[] DefaultArgumentNames
87 {
88 get
89 {
90 return new string[] { "r", "i", "dr", "R", "p", "Palette", "DimX", "DimY" };
91 }
92 }
93
98 public override bool IsAsynchronous => true;
99
104 {
105 return this.EvaluateAsync(Arguments, Variables).Result;
106 }
107
111 public override async Task<IElement> EvaluateAsync(IElement[] Arguments, Variables Variables)
112 {
113 string ColorExpression = null;
114 SKColor[] Palette;
115 object Obj;
116 double rc, ic;
117 double dr;
118 double Rr, Ri, pr, pi;
119 int dimx, dimy;
120 int i, c;
121
122 rc = Expression.ToDouble(Arguments[0].AssociatedObjectValue);
123 ic = Expression.ToDouble(Arguments[1].AssociatedObjectValue);
124 dr = Expression.ToDouble(Arguments[2].AssociatedObjectValue);
125
126 if ((Obj = Arguments[3].AssociatedObjectValue) is Complex)
127 {
128 Complex z = (Complex)Obj;
129 Rr = z.Real;
130 Ri = z.Imaginary;
131 }
132 else
133 {
134 Rr = Expression.ToDouble(Arguments[3].AssociatedObjectValue);
135 Ri = 0;
136 }
137
138 if ((Obj = Arguments[4].AssociatedObjectValue) is Complex)
139 {
140 Complex z = (Complex)Obj;
141 pr = z.Real;
142 pi = z.Imaginary;
143 }
144 else
145 {
146 pr = Expression.ToDouble(Arguments[4].AssociatedObjectValue);
147 pi = 0;
148 }
149
150 c = Arguments.Length;
151 i = 5;
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(128, 4, out int Seed, this, Variables);
161 ColorExpression = "RandomLinearAnalogousHSL(128,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 NovaSmoothFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
180 this);
181 }
182
183 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
184 throw new FractalImageSizeScriptException(this);
185
186 return await CalcNova(rc, ic, dr, Rr, Ri, pr, pi, Palette, dimx, dimy, this, Variables, this.FractalZoomScript,
187 new object[] { Palette, dimx, dimy, Rr, Ri, pr, pi, ColorExpression });
188 }
189
190 private string FractalZoomScript(double r, double i, double Size, object State)
191 {
192 object[] Parameters = (object[])State;
193 int DimX = (int)Parameters[1];
194 int DimY = (int)Parameters[2];
195 double Rr = (double)Parameters[3];
196 double Ri = (double)Parameters[4];
197 double pr = (double)Parameters[5];
198 double pi = (double)Parameters[6];
199 string ColorExpression = (string)Parameters[7];
200
201 StringBuilder sb = new StringBuilder();
202
203 sb.Append("NovaSmoothFractal(");
204 sb.Append(Expression.ToString(r));
205 sb.Append(',');
206 sb.Append(Expression.ToString(i));
207 sb.Append(',');
208 sb.Append(Expression.ToString(Size / 4));
209 sb.Append(',');
210 sb.Append(Expression.ToString(Rr));
211
212 if (Ri != 0)
213 {
214 sb.Append('+');
215 sb.Append(Expression.ToString(Ri));
216 sb.Append("*i");
217 }
218
219 sb.Append(',');
220 sb.Append(Expression.ToString(pr));
221
222 if (pi != 0)
223 {
224 sb.Append('+');
225 sb.Append(Expression.ToString(pi));
226 sb.Append("*i");
227 }
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 async Task<FractalGraph> CalcNova(double rCenter, double iCenter, double rDelta, double Rr, double Ri,
248 double pr, double pi, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables,
249 FractalZoomScript FractalZoomScript, object State)
250 {
251 double r0, i0, r1, i1;
252 double dr, di;
253 double r, i;
254 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
255 double aspect;
256 double Temp;
257 int x, y;
258 int n, N;
259 int index;
260 double lnz;
261 double argz;
262 double amp;
263 double phi;
264
265 N = Palette.Length;
266
267 rDelta *= 0.5;
268 r0 = rCenter - rDelta;
269 r1 = rCenter + rDelta;
270
271 aspect = ((double)Width) / Height;
272
273 i0 = iCenter - rDelta / aspect;
274 i1 = iCenter + rDelta / aspect;
275
276 dr = (r1 - r0) / Width;
277 di = (i1 - i0) / Height;
278
279 int Size = Width * Height;
280 double[] ColorIndex = new double[Size];
281 double Conv = 1e-10;
282 double Div = 1e10;
283
284 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
285 {
286 for (x = 0, r = r0; x < Width; x++, r += dr)
287 {
288 zr = r;
289 zi = i;
290
291 n = 0;
292 do
293 {
294 // f: z->z^p-1 = exp(p*ln(z))-1
295 // exp(a+ib)=exp(a)*(cos(b)+i*sin(b))
296 // ln(z)=ln|z|+i*arg(z)
297 // exp(p*ln(z))-1 =
298 // = exp((pr+i*pi)*(ln|z|+i*arg(z)))-1 =
299 // = exp(pr*ln|z|-pi*arg(z)+i*(pi*ln|z|+pr*arg(z)))-1 =
300 // = exp(pr*ln|z|-pi*arg(z))*(cos(pi*ln|z|+pr*arg(z))+i*sin(pi*ln|z|+pr*arg(z)))-1
301
302 lnz = Math.Log(Math.Sqrt(zr * zr + zi * zi));
303 argz = Math.Atan2(zi, zr);
304 amp = Math.Exp(pr * lnz - pi * argz);
305 phi = pi * lnz + pr * argz;
306
307 zr2 = amp * Math.Cos(phi) - 1;
308 zi2 = amp * Math.Sin(phi);
309
310 // f': z->p*z^(p-1) = p*exp((p-1)*ln(z)) =
311 // = (pr+i*pi)*exp((pr-1+i*pi)*(ln|z|+i*arg(z))) =
312 // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z)+i*(pi*ln|z|+(pr-1)*arg(z))) =
313 // = (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))) =
314
315 amp = Math.Exp((pr - 1) * lnz - pi * argz);
316 phi = pi * lnz + (pr - 1) * argz;
317
318 zr3 = amp * Math.Cos(phi);
319 zi3 = amp * Math.Sin(phi);
320
321 Temp = pr * zr3 - pi * zi3;
322 zi3 = pr * zi3 + pi * zr3;
323 zr3 = Temp;
324
325 // f/f':
326
327 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
328 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
329 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
330
331 Temp = Rr * zr4 - Ri * zi4;
332 zi4 = Ri * zr4 + Rr * zi4;
333 zr4 = Temp;
334
335 zr -= zr4;
336 zi -= zi4;
337
338 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
339 }
340 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
341
342 if (Temp < Conv && n < N)
343 ColorIndex[index++] = n;
344 else
345 ColorIndex[index++] = N;
346 }
347 }
348
349 await Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
350
351 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
352 await FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
353
354 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
355 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
356 }
357
361 public override string FunctionName => nameof(NovaSmoothFractal);
362 }
363}
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
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
NovaSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
static async Task< FractalGraph > CalcNova(double rCenter, double iCenter, 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
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
TODO
NovaSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
NovaSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, int Start, int Length, Expression Expression)
TODO
NovaSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
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