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