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;
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 NovaJuliaTopographyFractal(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 FractalImageSizeScriptException(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("NovaJuliaTopographyFractal(");
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 double r0, i0, r1, i1;
238 double dr, di;
239 double r, i;
240 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
241 double aspect;
242 double Temp;
243 int x, y;
244 int n, N;
245 int index;
246 double lnz;
247 double argz;
248 double amp;
249 double phi;
250
251 N = Palette.Length;
252
253 int Size = Width * Height;
254 int[] ColorIndex = new int[Size];
255 double Conv = 1e-10;
256 double Div = 1e10;
257
258 rDelta *= 0.5;
259 r0 = rCenter - rDelta;
260 r1 = rCenter + rDelta;
261
262 aspect = ((double)Width) / Height;
263
264 i0 = iCenter - rDelta / aspect;
265 i1 = iCenter + rDelta / aspect;
266
267 dr = (r1 - r0) / Width;
268 di = (i1 - i0) / Height;
269
270 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
271 {
272 for (x = 0, r = r0; x < Width; x++, r += dr)
273 {
274 zr = r;
275 zi = i;
276
277 n = 0;
278 do
279 {
280 // f: z->z^p-1 = exp(p*ln(z))-1
281 // exp(a+ib)=exp(a)*(cos(b)+i*sin(b))
282 // ln(z)=ln|z|+i*arg(z)
283 // exp(p*ln(z))-1 =
284 // = exp((pr+i*pi)*(ln|z|+i*arg(z)))-1 =
285 // = exp(pr*ln|z|-pi*arg(z)+i*(pi*ln|z|+pr*arg(z)))-1 =
286 // = exp(pr*ln|z|-pi*arg(z))*(cos(pi*ln|z|+pr*arg(z))+i*sin(pi*ln|z|+pr*arg(z)))-1
287
288 lnz = Math.Log(Math.Sqrt(zr * zr + zi * zi));
289 argz = Math.Atan2(zi, zr);
290 amp = Math.Exp(pr * lnz - pi * argz);
291 phi = pi * lnz + pr * argz;
292
293 zr2 = amp * Math.Cos(phi) - 1;
294 zi2 = amp * Math.Sin(phi);
295
296 // f': z->p*z^(p-1) = p*exp((p-1)*ln(z)) =
297 // = (pr+i*pi)*exp((pr-1+i*pi)*(ln|z|+i*arg(z))) =
298 // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z)+i*(pi*ln|z|+(pr-1)*arg(z))) =
299 // = (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))) =
300
301 amp = Math.Exp((pr - 1) * lnz - pi * argz);
302 phi = pi * lnz + (pr - 1) * argz;
303
304 zr3 = amp * Math.Cos(phi);
305 zi3 = amp * Math.Sin(phi);
306
307 Temp = pr * zr3 - pi * zi3;
308 zi3 = pr * zi3 + pi * zr3;
309 zr3 = Temp;
310
311 // f/f':
312
313 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
314 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
315 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
316
317 Temp = Rr * zr4 - Ri * zi4;
318 zi4 = Ri * zr4 + Rr * zi4 + I0;
319 zr4 = Temp + R0;
320
321 zr -= zr4;
322 zi -= zi4;
323
324 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
325 }
326 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
327
328 if (Temp < Conv && n < N)
329 ColorIndex[index++] = n;
330 else
331 ColorIndex[index++] = N;
332 }
333 }
334
335 ColorIndex = FractalGraph.FindBoundaries(ColorIndex, Width, Height);
336
337 return new FractalGraph(Variables, FractalGraph.ToPixels(ColorIndex, Width, Height, Palette),
338 r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State);
339 }
340
344 public override string FunctionName => nameof(NovaJuliaTopographyFractal);
345 }
346}
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 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
Exception thrown if an image with invalid size is requested.
Defines a clickable fractal graph in the complex plane.
Definition: FractalGraph.cs:23
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: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