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