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