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