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