Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
NovaMandelbrotSmoothFractal.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 NovaMandelbrotSmoothFractal(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(rc, ic, dr, Rr, Ri, pr, pi, Palette, dimx, dimy,
160 this, Variables, 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("NovaMandelbrotSmoothFractal(");
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(double rCenter, double iCenter, double rDelta, double Rr, double Ri,
222 double pr, double pi, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables,
223 FractalZoomScript FractalZoomScript, object State)
224 {
225 double r0, i0, r1, i1;
226 double dr, di;
227 double r, i;
228 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
229 double aspect;
230 double Temp;
231 int x, y;
232 int n, N;
233 int index;
234 double lnz;
235 double argz;
236 double amp;
237 double phi;
238
239 N = Palette.Length;
240
241 int size = Width * Height;
242 double[] ColorIndex = new double[size];
243 double Conv = 1e-10;
244 double Div = 1e10;
245
246 rDelta *= 0.5;
247 r0 = rCenter - rDelta;
248 r1 = rCenter + rDelta;
249
250 aspect = ((double)Width) / Height;
251
252 i0 = iCenter - rDelta / aspect;
253 i1 = iCenter + rDelta / aspect;
254
255 dr = (r1 - r0) / Width;
256 di = (i1 - i0) / Height;
257
258 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
259 {
260 for (x = 0, r = r0; x < Width; x++, r += dr)
261 {
262 zr = r;
263 zi = i;
264
265 n = 0;
266 do
267 {
268 // f: z->z^p-1 = exp(p*ln(z))-1
269 // exp(a+ib)=exp(a)*(cos(b)+i*sin(b))
270 // ln(z)=ln|z|+i*arg(z)
271 // exp(p*ln(z))-1 =
272 // = exp((pr+i*pi)*(ln|z|+i*arg(z)))-1 =
273 // = exp(pr*ln|z|-pi*arg(z)+i*(pi*ln|z|+pr*arg(z)))-1 =
274 // = exp(pr*ln|z|-pi*arg(z))*(cos(pi*ln|z|+pr*arg(z))+i*sin(pi*ln|z|+pr*arg(z)))-1
275
276 lnz = Math.Log(Math.Sqrt(zr * zr + zi * zi));
277 argz = Math.Atan2(zi, zr);
278 amp = Math.Exp(pr * lnz - pi * argz);
279 phi = pi * lnz + pr * argz;
280
281 zr2 = amp * Math.Cos(phi) - 1;
282 zi2 = amp * Math.Sin(phi);
283
284 // f': z->p*z^(p-1) = p*exp((p-1)*ln(z)) =
285 // = (pr+i*pi)*exp((pr-1+i*pi)*(ln|z|+i*arg(z))) =
286 // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z)+i*(pi*ln|z|+(pr-1)*arg(z))) =
287 // = (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))) =
288
289 amp = Math.Exp((pr - 1) * lnz - pi * argz);
290 phi = pi * lnz + (pr - 1) * argz;
291
292 zr3 = amp * Math.Cos(phi);
293 zi3 = amp * Math.Sin(phi);
294
295 Temp = pr * zr3 - pi * zi3;
296 zi3 = pr * zi3 + pi * zr3;
297 zr3 = Temp;
298
299 // f/f':
300
301 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
302 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
303 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
304
305 Temp = Rr * zr4 - Ri * zi4;
306 zi4 = Ri * zr4 + Rr * zi4 + i;
307 zr4 = Temp + r;
308
309 zr -= zr4;
310 zi -= zi4;
311
312 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
313 }
314 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
315
316 if (Temp < Conv && n < N)
317 ColorIndex[index++] = n;
318 else
319 ColorIndex[index++] = N;
320 }
321 }
322
323 Variables.Preview(Node.Expression, new GraphBitmap(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette)));
324
325 double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
326 FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables);
327
328 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
329 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
330 }
331
335 public override string FunctionName => nameof(NovaMandelbrotSmoothFractal);
336 }
337}
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)
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
static FractalGraph CalcNovaMandelbrot(double rCenter, double iCenter, double rDelta, double Rr, double Ri, double pr, double pi, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
NovaMandelbrotSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
NovaMandelbrotSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
NovaMandelbrotSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
NovaMandelbrotSmoothFractal(ScriptNode r, ScriptNode i, ScriptNode dr, ScriptNode R, ScriptNode p, int Start, int Length, Expression Expression)
TODO
Defines a clickable fractal graph in the complex plane.
Definition: FractalGraph.cs:22
static PixelInformation ToPixels(double[] ColorIndex, int Width, int Height, SKColor[] Palette)
TODO
static SKColor[] ToPalette(ObjectVector Vector)
TODO
static double[] FindBoundaries(double[] ColorIndex, int Width, int Height)
TODO
static void Smooth(double[] ColorIndex, double[] Boundary, int Width, int Height, int N, SKColor[] Palette, ScriptNode Node, Variables Variables)
TODO
Handles bitmap-based graphs.
Definition: GraphBitmap.cs:13
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
void Preview(Expression Expression, IElement Result)
Reports a preview of the final result.
Definition: Variables.cs:455
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