Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
NovaFractal.cs
1using System;
2using System.Numerics;
3using System.Text;
4using SkiaSharp;
10
12{
32 {
37 ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
38 : base(new ScriptNode[] { r, i, dr, R, p, Palette, DimX, DimY },
39 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
40 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Vector, ArgumentType.Scalar,
42 {
43 }
44
49 ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
50 : base(new ScriptNode[] { r, i, dr, R, p, Palette, DimX },
51 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
52 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Vector, ArgumentType.Scalar },
54 {
55 }
56
61 ScriptNode Palette, int Start, int Length, Expression Expression)
62 : base(new ScriptNode[] { r, i, dr, R, p, Palette },
63 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
64 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Vector },
66 {
67 }
68
74 : base(new ScriptNode[] { r, i, dr, R, p },
75 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
76 ArgumentType.Scalar, ArgumentType.Scalar },
78 {
79 }
80
84 public override string[] DefaultArgumentNames
85 {
86 get
87 {
88 return new string[] { "r", "i", "dr", "R", "p", "Palette", "DimX", "DimY" };
89 }
90 }
91
96 {
97 string ColorExpression = null;
98 SKColor[] Palette;
99 object Obj;
100 double rc, ic;
101 double dr;
102 double Rr, Ri, pr, pi;
103 int dimx, dimy;
104 int i, c;
105
106 rc = Expression.ToDouble(Arguments[0].AssociatedObjectValue);
107 ic = Expression.ToDouble(Arguments[1].AssociatedObjectValue);
108 dr = Expression.ToDouble(Arguments[2].AssociatedObjectValue);
109
110 if ((Obj = Arguments[3].AssociatedObjectValue) is Complex)
111 {
112 Complex z = (Complex)Obj;
113 Rr = z.Real;
114 Ri = z.Imaginary;
115 }
116 else
117 {
118 Rr = Expression.ToDouble(Arguments[3].AssociatedObjectValue);
119 Ri = 0;
120 }
121
122 if ((Obj = Arguments[4].AssociatedObjectValue) is Complex)
123 {
124 Complex z = (Complex)Obj;
125 pr = z.Real;
126 pi = z.Imaginary;
127 }
128 else
129 {
130 pr = Expression.ToDouble(Arguments[4].AssociatedObjectValue);
131 pi = 0;
132 }
133
134 c = Arguments.Length;
135 i = 5;
136
137 if (i < c && !(this.Arguments[i] is null) && Arguments[i] is ObjectVector)
138 {
139 ColorExpression = this.Arguments[i].SubExpression;
141 }
142 else
143 {
144 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out int Seed, this, Variables);
145 ColorExpression = "RandomLinearAnalogousHSL(128,4," + Seed.ToString() + ")";
146
147 if (i < c && this.Arguments[i] is null)
148 i++;
149 }
150
151 if (i < c)
152 dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
153 else
154 dimx = 320;
155
156 if (i < c)
157 dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
158 else
159 dimy = 200;
160
161 if (i < c)
162 {
163 throw new ScriptRuntimeException("Parameter mismatch in call to NovaFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
164 this);
165 }
166
167 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
168 throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
169
170 return CalcNova(Variables, rc, ic, dr, Rr, Ri, pr, pi, Palette, dimx, dimy, this, this.FractalZoomScript,
171 new object[] { Palette, dimx, dimy, Rr, Ri, pr, pi, ColorExpression });
172 }
173
174 private string FractalZoomScript(double r, double i, double Size, object State)
175 {
176 object[] Parameters = (object[])State;
177 int DimX = (int)Parameters[1];
178 int DimY = (int)Parameters[2];
179 double Rr = (double)Parameters[3];
180 double Ri = (double)Parameters[4];
181 double pr = (double)Parameters[5];
182 double pi = (double)Parameters[6];
183 string ColorExpression = (string)Parameters[7];
184
185 StringBuilder sb = new StringBuilder();
186
187 sb.Append("NovaFractal(");
188 sb.Append(Expression.ToString(r));
189 sb.Append(',');
190 sb.Append(Expression.ToString(i));
191 sb.Append(',');
192 sb.Append(Expression.ToString(Size / 4));
193 sb.Append(',');
194 sb.Append(Expression.ToString(Rr));
195
196 if (Ri != 0)
197 {
198 sb.Append('+');
199 sb.Append(Expression.ToString(Ri));
200 sb.Append("*i");
201 }
202
203 sb.Append(',');
204 sb.Append(Expression.ToString(pr));
205
206 if (pi != 0)
207 {
208 sb.Append('+');
209 sb.Append(Expression.ToString(pi));
210 sb.Append("*i");
211 }
212
213 if (!string.IsNullOrEmpty(ColorExpression))
214 {
215 sb.Append(',');
216 sb.Append(ColorExpression);
217 }
218
219 sb.Append(',');
220 sb.Append(DimX.ToString());
221 sb.Append(',');
222 sb.Append(DimY.ToString());
223 sb.Append(')');
224
225 return sb.ToString();
226 }
227
231 public static FractalGraph CalcNova(Variables Variables, double rCenter, double iCenter, double rDelta, double Rr, double Ri,
232 double pr, double pi, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
233 {
234 byte[] reds;
235 byte[] greens;
236 byte[] blues;
237 double r0, i0, r1, i1;
238 double dr, di;
239 double r, i;
240 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
241 double aspect;
242 double Temp;
243 int x, y;
244 int n, N;
245 int index;
246 SKColor cl;
247 double lnz;
248 double argz;
249 double amp;
250 double phi;
251
252 N = Palette.Length;
253 reds = new byte[N];
254 greens = new byte[N];
255 blues = new byte[N];
256
257 for (x = 0; x < N; x++)
258 {
259 cl = Palette[x];
260 reds[x] = cl.Red;
261 greens[x] = cl.Green;
262 blues[x] = cl.Blue;
263 }
264
265 int size = Width * Height * 4;
266 double Conv = 1e-10;
267 double Div = 1e10;
268 byte[] rgb = new byte[size];
269
270 rDelta *= 0.5;
271 r0 = rCenter - rDelta;
272 r1 = rCenter + rDelta;
273
274 aspect = ((double)Width) / Height;
275
276 i0 = iCenter - rDelta / aspect;
277 i1 = iCenter + rDelta / aspect;
278
279 dr = (r1 - r0) / Width;
280 di = (i1 - i0) / Height;
281
282 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
283 {
284 for (x = 0, r = r0; x < Width; x++, r += dr)
285 {
286 zr = r;
287 zi = i;
288
289 n = 0;
290 do
291 {
292 // f: z->z^p-1 = exp(p*ln(z))-1
293 // exp(a+ib)=exp(a)*(cos(b)+i*sin(b))
294 // ln(z)=ln|z|+i*arg(z)
295 // exp(p*ln(z))-1 =
296 // = exp((pr+i*pi)*(ln|z|+i*arg(z)))-1 =
297 // = exp(pr*ln|z|-pi*arg(z)+i*(pi*ln|z|+pr*arg(z)))-1 =
298 // = exp(pr*ln|z|-pi*arg(z))*(cos(pi*ln|z|+pr*arg(z))+i*sin(pi*ln|z|+pr*arg(z)))-1
299
300 lnz = Math.Log(Math.Sqrt(zr * zr + zi * zi));
301 argz = Math.Atan2(zi, zr);
302 amp = Math.Exp(pr * lnz - pi * argz);
303 phi = pi * lnz + pr * argz;
304
305 zr2 = amp * Math.Cos(phi) - 1;
306 zi2 = amp * Math.Sin(phi);
307
308 // f': z->p*z^(p-1) = p*exp((p-1)*ln(z)) =
309 // = (pr+i*pi)*exp((pr-1+i*pi)*(ln|z|+i*arg(z))) =
310 // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z)+i*(pi*ln|z|+(pr-1)*arg(z))) =
311 // = (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))) =
312
313 amp = Math.Exp((pr - 1) * lnz - pi * argz);
314 phi = pi * lnz + (pr - 1) * argz;
315
316 zr3 = amp * Math.Cos(phi);
317 zi3 = amp * Math.Sin(phi);
318
319 Temp = pr * zr3 - pi * zi3;
320 zi3 = pr * zi3 + pi * zr3;
321 zr3 = Temp;
322
323 // f/f':
324
325 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
326 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
327 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
328
329 Temp = Rr * zr4 - Ri * zi4;
330 zi4 = Ri * zr4 + Rr * zi4;
331 zr4 = Temp;
332
333 zr -= zr4;
334 zi -= zi4;
335
336 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
337 }
338 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
339
340 if (Temp < Conv && n < N)
341 {
342 rgb[index++] = blues[n];
343 rgb[index++] = greens[n];
344 rgb[index++] = reds[n];
345 }
346 else
347 {
348 rgb[index++] = 0;
349 rgb[index++] = 0;
350 rgb[index++] = 0;
351 }
352
353 rgb[index++] = 255;
354 }
355 }
356
357 PixelInformation Pixels = new PixelInformationRaw(SKColorType.Bgra8888, rgb, Width, Height, Width << 2);
358 return new FractalGraph(Variables, Pixels, r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
359 }
360
364 public override string FunctionName => nameof(NovaFractal);
365 }
366}
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
NovaFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, int Start, int Length, Expression Expression)
TODO
Definition: NovaFractal.cs:72
static FractalGraph CalcNova(Variables Variables, double rCenter, double iCenter, double rDelta, double Rr, double Ri, double pr, double pi, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
Definition: NovaFractal.cs:231
NovaFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
Definition: NovaFractal.cs:48
NovaFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
Definition: NovaFractal.cs:60
NovaFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
Definition: NovaFractal.cs:36
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
Definition: NovaFractal.cs:95
Defines a clickable fractal graph in the complex plane.
Definition: FractalGraph.cs:22
static SKColor[] ToPalette(ObjectVector Vector)
TODO
Contains pixel information
Contains pixel information in a raw unencoded format.
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
Basic interface for all types of elements.
Definition: IElement.cs:20
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