Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
NovaJuliaTopographyFractal.cs
1using System;
2using System.Numerics;
3using System.Text;
4using SkiaSharp;
9
11{
19 {
24 ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY,
26 : base(new ScriptNode[] { r, i, r0, i0, dr, R, p, Palette, DimX, DimY },
27 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
28 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
29 ArgumentType.Vector, ArgumentType.Scalar, ArgumentType.Scalar},
31 {
32 }
33
38 ScriptNode R, ScriptNode p, ScriptNode Palette, ScriptNode DimX, int Start, int Length,
40 : base(new ScriptNode[] { r, i, r0, i0, dr, R, p, Palette, DimX },
41 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
42 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
43 ArgumentType.Vector, ArgumentType.Scalar },
45 {
46 }
47
53 : base(new ScriptNode[] { r, i, r0, i0, dr, R, p, Palette },
54 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
55 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
56 ArgumentType.Vector },
58 {
59 }
60
66 : base(new ScriptNode[] { r, i, r0, i0, dr, R, p },
67 new ArgumentType[] { ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar,
68 ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar, ArgumentType.Scalar },
70 {
71 }
72
76 public override string[] DefaultArgumentNames
77 {
78 get
79 {
80 return new string[] { "r", "i", "r0", "i0", "dr", "R", "p", "Palette", "DimX", "DimY" };
81 }
82 }
83
88 {
89 string ColorExpression = null;
90 SKColor[] Palette;
91 object Obj;
92 double rc, ic;
93 double r0, i0;
94 double dr;
95 double Rr, Ri, pr, pi;
96 int dimx, dimy;
97 int i, c;
98
99 rc = Expression.ToDouble(Arguments[0].AssociatedObjectValue);
100 ic = Expression.ToDouble(Arguments[1].AssociatedObjectValue);
101 r0 = Expression.ToDouble(Arguments[2].AssociatedObjectValue);
102 i0 = Expression.ToDouble(Arguments[3].AssociatedObjectValue);
103 dr = Expression.ToDouble(Arguments[4].AssociatedObjectValue);
104
105 if ((Obj = Arguments[5].AssociatedObjectValue) is Complex)
106 {
107 Complex z = (Complex)Obj;
108 Rr = z.Real;
109 Ri = z.Imaginary;
110 }
111 else
112 {
113 Rr = Expression.ToDouble(Arguments[5].AssociatedObjectValue);
114 Ri = 0;
115 }
116
117 if ((Obj = Arguments[6].AssociatedObjectValue) is Complex)
118 {
119 Complex z = (Complex)Obj;
120 pr = z.Real;
121 pi = z.Imaginary;
122 }
123 else
124 {
125 pr = Expression.ToDouble(Arguments[6].AssociatedObjectValue);
126 pi = 0;
127 }
128
129 c = Arguments.Length;
130 i = 7;
131
132 if (i < c && !(this.Arguments[i] is null) && Arguments[i] is ObjectVector)
133 {
134 ColorExpression = this.Arguments[i].SubExpression;
136 }
137 else
138 {
139 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(1024, 16, out int Seed, this, Variables);
140 ColorExpression = "RandomLinearAnalogousHSL(1024,16," + Seed.ToString() + ")";
141
142 if (i < c && this.Arguments[i] is null)
143 i++;
144 }
145
146 if (i < c)
147 dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
148 else
149 dimx = 320;
150
151 if (i < c)
152 dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
153 else
154 dimy = 200;
155
156 if (i < c)
157 {
158 throw new ScriptRuntimeException("Parameter mismatch in call to NovaJuliaTopographyFractal(r,c,r0,i0,dr,Coefficients[,Palette][,dimx[,dimy]]).",
159 this);
160 }
161
162 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
163 throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
164
165 return CalcNovaJulia(Variables, rc, ic, r0, i0, dr, Rr, Ri, pr, pi, Palette, dimx, dimy, this, this.FractalZoomScript,
166 new object[] { Palette, dimx, dimy, r0, i0, Rr, Ri, pr, pi, ColorExpression });
167 }
168
169 private string FractalZoomScript(double r, double i, double Size, object State)
170 {
171 object[] Parameters = (object[])State;
172 int DimX = (int)Parameters[1];
173 int DimY = (int)Parameters[2];
174 double r0 = (double)Parameters[3];
175 double i0 = (double)Parameters[4];
176 double Rr = (double)Parameters[5];
177 double Ri = (double)Parameters[6];
178 double pr = (double)Parameters[7];
179 double pi = (double)Parameters[8];
180 string ColorExpression = (string)Parameters[9];
181
182 StringBuilder sb = new StringBuilder();
183
184 sb.Append("NovaJuliaTopographyFractal(");
185 sb.Append(Expression.ToString(r));
186 sb.Append(',');
187 sb.Append(Expression.ToString(i));
188 sb.Append(',');
189 sb.Append(Expression.ToString(r0));
190 sb.Append(',');
191 sb.Append(Expression.ToString(i0));
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 CalcNovaJulia(Variables Variables, double rCenter, double iCenter, double R0, double I0,
233 double rDelta, double Rr, double Ri, double pr, double pi, SKColor[] Palette, int Width, int Height, ScriptNode Node,
234 FractalZoomScript FractalZoomScript, object State)
235 {
236 double r0, i0, r1, i1;
237 double dr, di;
238 double r, i;
239 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
240 double aspect;
241 double Temp;
242 int x, y;
243 int n, N;
244 int index;
245 double lnz;
246 double argz;
247 double amp;
248 double phi;
249
250 N = Palette.Length;
251
252 int Size = Width * Height;
253 int[] ColorIndex = new int[Size];
254 double Conv = 1e-10;
255 double Div = 1e10;
256
257 rDelta *= 0.5;
258 r0 = rCenter - rDelta;
259 r1 = rCenter + rDelta;
260
261 aspect = ((double)Width) / Height;
262
263 i0 = iCenter - rDelta / aspect;
264 i1 = iCenter + rDelta / aspect;
265
266 dr = (r1 - r0) / Width;
267 di = (i1 - i0) / Height;
268
269 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
270 {
271 for (x = 0, r = r0; x < Width; x++, r += dr)
272 {
273 zr = r;
274 zi = i;
275
276 n = 0;
277 do
278 {
279 // f: z->z^p-1 = exp(p*ln(z))-1
280 // exp(a+ib)=exp(a)*(cos(b)+i*sin(b))
281 // ln(z)=ln|z|+i*arg(z)
282 // exp(p*ln(z))-1 =
283 // = exp((pr+i*pi)*(ln|z|+i*arg(z)))-1 =
284 // = exp(pr*ln|z|-pi*arg(z)+i*(pi*ln|z|+pr*arg(z)))-1 =
285 // = exp(pr*ln|z|-pi*arg(z))*(cos(pi*ln|z|+pr*arg(z))+i*sin(pi*ln|z|+pr*arg(z)))-1
286
287 lnz = Math.Log(Math.Sqrt(zr * zr + zi * zi));
288 argz = Math.Atan2(zi, zr);
289 amp = Math.Exp(pr * lnz - pi * argz);
290 phi = pi * lnz + pr * argz;
291
292 zr2 = amp * Math.Cos(phi) - 1;
293 zi2 = amp * Math.Sin(phi);
294
295 // f': z->p*z^(p-1) = p*exp((p-1)*ln(z)) =
296 // = (pr+i*pi)*exp((pr-1+i*pi)*(ln|z|+i*arg(z))) =
297 // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z)+i*(pi*ln|z|+(pr-1)*arg(z))) =
298 // = (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))) =
299
300 amp = Math.Exp((pr - 1) * lnz - pi * argz);
301 phi = pi * lnz + (pr - 1) * argz;
302
303 zr3 = amp * Math.Cos(phi);
304 zi3 = amp * Math.Sin(phi);
305
306 Temp = pr * zr3 - pi * zi3;
307 zi3 = pr * zi3 + pi * zr3;
308 zr3 = Temp;
309
310 // f/f':
311
312 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
313 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
314 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
315
316 Temp = Rr * zr4 - Ri * zi4;
317 zi4 = Ri * zr4 + Rr * zi4 + I0;
318 zr4 = Temp + R0;
319
320 zr -= zr4;
321 zi -= zi4;
322
323 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
324 }
325 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
326
327 if (Temp < Conv && n < N)
328 ColorIndex[index++] = n;
329 else
330 ColorIndex[index++] = N;
331 }
332 }
333
334 ColorIndex = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
335
336 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
337 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
338 }
339
343 public override string FunctionName => nameof(NovaJuliaTopographyFractal);
344 }
345}
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 Topography Fractal Image (by Paul Derbyshire)
NovaJuliaTopographyFractal(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
NovaJuliaTopographyFractal(ScriptNode r, ScriptNode i, ScriptNode r0, ScriptNode i0, ScriptNode dr, ScriptNode R, ScriptNode p, int Start, int Length, Expression Expression)
TODO
NovaJuliaTopographyFractal(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
NovaJuliaTopographyFractal(ScriptNode r, ScriptNode i, ScriptNode r0, ScriptNode i0, ScriptNode dr, ScriptNode R, ScriptNode p, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
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
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
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