54 : base(new
ScriptNode[] { z, dr, R, c, Palette, DimX, DimY },
66 : base(new
ScriptNode[] { z, dr, R, c, Palette, DimX },
78 : base(new
ScriptNode[] { z, dr, R, c, Palette },
92 ArgumentType.Normal },
104 return new string[] {
"z",
"dr",
"R",
"c",
"Palette",
"DimX",
"DimY" };
113 string ColorExpression =
null;
115 double[] Coefficients =
null;
116 Complex[] CoefficientsZ =
null;
127 Obj =
Arguments[i++].AssociatedObjectValue;
128 if (Obj is Complex z)
144 if (i < c && ((Obj =
Arguments[i].AssociatedObjectValue) is
double || Obj is Complex))
153 if (i < c && this.Arguments[i] is
null)
160 Coefficients = (
double[])
Arguments[i++].AssociatedObjectValue;
162 CoefficientsZ = (Complex[])
Arguments[i++].AssociatedObjectValue;
172 CoefficientsZ =
new Complex[d];
173 for (j = 0; j < d; j++)
180 throw new ScriptRuntimeException(
"Lambda expression in calls to NewtonFractal() must be of one variable.",
this);
182 fDef = this.Arguments[i++];
187 " in call to NewtonFractal has to be a vector of numbers, containing coefficients " +
188 "of the polynomial to use. Now it was of type " +
Arguments[i].GetType().FullName,
197 ColorExpression = this.Arguments[i].SubExpression;
202 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out
int Seed,
this,
Variables);
203 ColorExpression =
"RandomLinearAnalogousHSL(128,4," + Seed.ToString() +
")";
205 if (i < c && this.Arguments[i] is
null)
221 throw new ScriptRuntimeException(
"Parameter mismatch in call to NewtonFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
225 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
230 return CalcNewton(rc, ic, dr, R, f, fDef,
Variables, Palette, dimx, dimy,
231 this, this.FractalZoomScript,
new object[] { Palette, dimx, dimy, R, fDef, ColorExpression });
233 else if (!(CoefficientsZ is
null))
236 this, this.FractalZoomScript,
new object[] { Palette, dimx, dimy, R, CoefficientsZ, ColorExpression });
241 this, this.FractalZoomScript,
new object[] { Palette, dimx, dimy, R, Coefficients, ColorExpression });
245 private string FractalZoomScript(
double r,
double i,
double Size,
object State)
247 object[] Parameters = (
object[])State;
248 int DimX = (int)Parameters[1];
249 int DimY = (int)Parameters[2];
250 Complex R = (Complex)Parameters[3];
251 double[] Coefficients = Parameters[4] as
double[];
252 string ColorExpression = (string)Parameters[5];
254 StringBuilder sb =
new StringBuilder();
256 sb.Append(
"NewtonFractal((");
267 sb.Append(fDef.SubExpression);
268 else if (Parameters[4] is Complex[] CoefficientsZ)
273 if (!
string.IsNullOrEmpty(ColorExpression))
276 sb.Append(ColorExpression);
280 sb.Append(DimX.ToString());
282 sb.Append(DimY.ToString());
285 return sb.ToString();
292 double[] Coefficients, SKColor[] Palette,
int Width,
int Height,
ScriptNode Node, FractalZoomScript FractalZoomScript,
298 double r0, i0, r1, i1;
301 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
303 double RIm = R.Imaginary;
309 int Degree = Coefficients.Length - 1;
314 greens =
new byte[N];
317 for (x = 0; x < N; x++)
321 greens[x] = cl.Green;
327 Array.Resize(ref Coefficients, 3);
329 Coefficients[++Degree] = 0;
332 double[] Prim =
new double[Degree];
333 for (x = 1; x <= Degree; x++)
334 Prim[x - 1] = x * Coefficients[x];
337 Coefficients = (
double[])Coefficients.Clone();
338 Array.Reverse(Coefficients);
340 int size = Width * Height * 4;
343 byte[] rgb =
new byte[size];
346 r0 = rCenter - rDelta;
347 r1 = rCenter + rDelta;
349 aspect = ((double)Width) / Height;
351 i0 = iCenter - rDelta / aspect;
352 i1 = iCenter + rDelta / aspect;
354 dr = (r1 - r0) / Width;
355 di = (i1 - i0) / Height;
357 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
359 for (x = 0, r = r0; x < Width; x++, r += dr)
369 foreach (
double C
in Coefficients)
371 Temp = zr2 * zr - zi2 * zi + C;
372 zi2 = zr2 * zi + zi2 * zr;
378 foreach (
double C
in Prim)
380 Temp = zr3 * zr - zi3 * zi + C;
381 zi3 = zr3 * zi + zi3 * zr;
387 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
388 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
389 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
392 Temp = zr4 * RRe - zi4 * RIm;
393 zi4 = zr4 * RIm + zi4 * RRe;
399 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
401 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
403 if (Temp < Conv && n < N)
405 rgb[index++] = blues[n];
406 rgb[index++] = greens[n];
407 rgb[index++] = reds[n];
421 return new FractalGraph(
Variables, Pixels, r0, i0, r1, i1, rDelta * 2,
true, Node,
FractalZoomScript, State);
428 Complex[] Coefficients, SKColor[] Palette,
int Width,
int Height,
ScriptNode Node, FractalZoomScript FractalZoomScript,
435 double RIm = R.Imaginary;
436 double r0, i0, r1, i1;
439 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
445 int Degree = Coefficients.Length - 1;
450 greens =
new byte[N];
453 for (x = 0; x < N; x++)
457 greens[x] = cl.Green;
463 Array.Resize(ref Coefficients, 3);
465 Coefficients[++Degree] = Complex.Zero;
468 Complex[] Prim =
new Complex[Degree];
469 for (x = 1; x <= Degree; x++)
470 Prim[x - 1] = x * Coefficients[x];
473 Coefficients = (Complex[])Coefficients.Clone();
474 Array.Reverse(Coefficients);
476 int j, c = Prim.Length;
477 double[] ReC =
new double[c + 1];
478 double[] ImC =
new double[c + 1];
479 double[] RePrim =
new double[c];
480 double[] ImPrim =
new double[c];
483 for (j = 0; j < c; j++)
487 ImC[j] = z.Imaginary;
491 ImPrim[j] = z.Imaginary;
496 ImC[j] = z.Imaginary;
498 int size = Width * Height * 4;
501 byte[] rgb =
new byte[size];
504 r0 = rCenter - rDelta;
505 r1 = rCenter + rDelta;
507 aspect = ((double)Width) / Height;
509 i0 = iCenter - rDelta / aspect;
510 i1 = iCenter + rDelta / aspect;
512 dr = (r1 - r0) / Width;
513 di = (i1 - i0) / Height;
515 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
517 for (x = 0, r = r0; x < Width; x++, r += dr)
527 for (j = 0; j <= c; j++)
529 Temp = zr2 * zr - zi2 * zi + ReC[j];
530 zi2 = zr2 * zi + zi2 * zr + ImC[j];
536 for (j = 0; j < c; j++)
538 Temp = zr3 * zr - zi3 * zi + RePrim[j];
539 zi3 = zr3 * zi + zi3 * zr + ImPrim[j];
545 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
546 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
547 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
550 Temp = zr4 * RRe - zi4 * RIm;
551 zi4 = zr4 * RIm + zi4 * RRe;
557 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
559 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
561 if (Temp < Conv && n < N)
563 rgb[index++] = blues[n];
564 rgb[index++] = greens[n];
565 rgb[index++] = reds[n];
579 return new FractalGraph(
Variables, Pixels, r0, i0, r1, i1, rDelta * 2,
true, Node,
FractalZoomScript, State);
587 ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
593 double RIm = R.Imaginary;
594 double r0, i0, r1, i1;
605 greens =
new byte[N];
608 for (x = 0; x < N; x++)
612 greens[x] = cl.Green;
620 !(Differentiable.Differentiate(Differentiable.DefaultVariableName, v) is
ILambdaExpression fPrim))
625 int size = Width * Height * 4;
628 byte[] rgb =
new byte[size];
640 r0 = rCenter - rDelta;
641 r1 = rCenter + rDelta;
643 aspect = ((double)Width) / Height;
645 i0 = iCenter - rDelta / aspect;
646 i1 = iCenter + rDelta / aspect;
648 dr = (r1 - r0) / Width;
649 di = (i1 - i0) / Height;
651 for (y = 0, i = i0; y < Height; y++, i += di)
653 Row =
new Complex[Width];
654 Offset =
new int[Width];
657 for (x = 0, x2 = y * Width * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
659 Row[x] =
new Complex(r, i);
664 while (n < N && c > 0)
669 Obj2 = fPrim.Evaluate(P, v);
670 Row2 = Obj.AssociatedObjectValue as Complex[];
671 Row3 = Obj2.AssociatedObjectValue as Complex[];
673 if (Row2 is
null || Row3 is
null)
675 throw new ScriptRuntimeException(
"Lambda expression (and its first derivative) must be able to accept complex vectors, " +
676 "and return complex vectors of equal length. Type returned: " +
677 Obj.GetType().FullName +
" and " + Obj2.GetType().FullName, Node);
679 else if (Row2.Length != c || Row3.Length != c)
681 throw new ScriptRuntimeException(
"Lambda expression (and its first derivative) must be able to accept complex vectors, " +
682 "and return complex vectors of equal length. Length returned: " +
683 Row2.Length.ToString() +
" and " + Row3.Length.ToString() +
684 ". Expected: " + c.ToString(), Node);
687 for (x = x2 = 0; x < c; x++)
690 z = R * Row2[x] / Row3[x];
695 if (Mod > Conv && Mod < Div)
713 rgb[j++] = greens[n];
723 Array.Resize(ref Row, x2);
724 Array.Resize(ref Offset, x2);
731 return new FractalGraph(
Variables, Pixels, r0, i0, r1, i1, rDelta * 2,
true, Node,
FractalZoomScript, State);
Script runtime exception.
Class managing a script expression.
static Complex ToComplex(object Object)
Converts an object to a complex value.
static double ToDouble(object Object)
Converts an object to a double value.
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Calculates a Newton Fractal Image
static FractalGraph CalcNewton(Variables Variables, double rCenter, double iCenter, double rDelta, Complex R, Complex[] Coefficients, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
NewtonFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
static FractalGraph CalcNewton(double rCenter, double iCenter, double rDelta, Complex R, ILambdaExpression f, ScriptNode _, Variables Variables, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
override string FunctionName
TODO
NewtonFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
NewtonFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, int Start, int Length, Expression Expression)
TODO
NewtonFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
static FractalGraph CalcNewton(Variables Variables, double rCenter, double iCenter, double rDelta, Complex R, double[] Coefficients, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
override string[] DefaultArgumentNames
TODO
Exception thrown if an image with invalid size is requested.
Defines a clickable fractal graph in the complex plane.
static SKColor[] ToPalette(ObjectVector Vector)
TODO
Base class for multivariate funcions.
ScriptNode[] Arguments
Function arguments.
Base class for all nodes in a parsed script tree.
int Length
Length of expression covered by node.
override string ToString()
Expression Expression
Expression of which the node is a part.
int Start
Start position in script expression.
void CopyTo(Variables Variables)
Copies available variables to another variable collection.
Basic interface for all types of elements.
object AssociatedObjectValue
Associated object value.
Basic interface for vectors.
int Dimension
Dimension of vector.
IElement GetElement(int Index)
Gets an element of the vector.
Base interface for lambda expressions.
Base interface for lambda expressions.
IElement Evaluate(IElement[] Arguments, Variables Variables)
Evaluates the lambda expression.
int NrArguments
Number of arguments.
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.