4using System.Threading.Tasks;
49 : base(new
ScriptNode[] { z, dr, R, Coefficients, Palette, DimX, DimY },
60 : base(new
ScriptNode[] { z, dr, R, Coefficients, Palette, DimX },
71 : base(new
ScriptNode[] { z, dr, R, Coefficients, Palette },
82 : base(new
ScriptNode[] { z, dr, R, Coefficients },
113 return new string[] {
"z",
"dr",
"R",
"Coefficients",
"Palette",
"DimX",
"DimY" };
136 string ColorExpression =
null;
138 double[] Coefficients =
null;
139 Complex[] CoefficientsZ =
null;
150 Obj =
Arguments[i++].AssociatedObjectValue;
151 if (Obj is Complex z)
167 if (i < c && ((Obj =
Arguments[i].AssociatedObjectValue) is
double || Obj is Complex))
176 if (i < c && this.Arguments[i] is
null)
183 Coefficients = (
double[])
Arguments[i++].AssociatedObjectValue;
185 CoefficientsZ = (Complex[])
Arguments[i++].AssociatedObjectValue;
195 CoefficientsZ =
new Complex[d];
196 for (j = 0; j < d; j++)
203 throw new ScriptRuntimeException(
"Lambda expression in calls to HalleySmoothFractal() must be of one variable.",
this);
205 fDef = this.Arguments[i++];
210 " in call to HalleySmoothFractal has to be a vector of numbers, containing coefficients " +
211 "of the polynomial to use. Now it was of type " +
Arguments[i].GetType().FullName,
220 ColorExpression = this.Arguments[i].SubExpression;
225 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out
int Seed,
this,
Variables);
226 ColorExpression =
"RandomLinearAnalogousHSL(128,4," + Seed.ToString() +
")";
228 if (i < c && this.Arguments[i] is
null)
244 throw new ScriptRuntimeException(
"Parameter mismatch in call to HalleySmoothFractal(z,dr[,R][,Coefficients][,Palette][,dimx[,dimy]]).",
248 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
253 return await
CalcHalley(rc, ic, dr, R, f,
Variables, Palette, dimx, dimy,
this, this.FractalZoomScript,
254 new object[] { Palette, dimx, dimy, R, fDef, ColorExpression });
256 else if (!(CoefficientsZ is
null))
258 return await
CalcHalley(rc, ic, dr, R, CoefficientsZ, Palette, dimx, dimy,
260 new object[] { Palette, dimx, dimy, R, CoefficientsZ, ColorExpression });
264 return await
CalcHalley(rc, ic, dr, R, Coefficients, Palette, dimx, dimy,
266 new object[] { Palette, dimx, dimy, R, Coefficients, ColorExpression });
270 private string FractalZoomScript(
double r,
double i,
double Size,
object State)
272 object[] Parameters = (
object[])State;
274 int DimX = (int)Parameters[1];
275 int DimY = (int)Parameters[2];
276 Complex R = (Complex)Parameters[3];
277 string ColorExpression = (string)Parameters[5];
279 StringBuilder sb =
new StringBuilder();
281 sb.Append(
"HalleySmoothFractal((");
292 sb.Append(fDef.SubExpression);
293 else if (Parameters[4] is Complex[] CoefficientsZ)
295 else if (Parameters[4] is
double[] Coefficients)
298 if (!
string.IsNullOrEmpty(ColorExpression))
301 sb.Append(ColorExpression);
305 sb.Append(DimX.ToString());
307 sb.Append(DimY.ToString());
310 return sb.ToString();
316 public static async Task<FractalGraph>
CalcHalley(
double rCenter,
double iCenter,
double rDelta, Complex R,
318 FractalZoomScript FractalZoomScript,
object State)
321 double RIm = R.Imaginary;
322 double r0, i0, r1, i1;
325 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4, zr5, zi5, zr6, zi6;
331 int Degree = Coefficients.Length - 1;
337 Array.Resize(ref Coefficients, 4);
339 Coefficients[++Degree] = 0;
342 double[] Prim =
new double[Degree];
343 for (x = 1; x <= Degree; x++)
344 Prim[x - 1] = x * Coefficients[x];
346 double[] Bis =
new double[Degree - 1];
347 for (x = 1; x < Degree; x++)
348 Bis[x - 1] = x * Prim[x];
352 Coefficients = (
double[])Coefficients.Clone();
353 Array.Reverse(Coefficients);
355 int size = Width * Height;
356 double[] ColorIndex =
new double[size];
361 r0 = rCenter - rDelta;
362 r1 = rCenter + rDelta;
364 aspect = ((double)Width) / Height;
366 i0 = iCenter - rDelta / aspect;
367 i1 = iCenter + rDelta / aspect;
369 dr = (r1 - r0) / Width;
370 di = (i1 - i0) / Height;
372 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
374 for (x = 0, r = r0; x < Width; x++, r += dr)
384 foreach (
double C
in Coefficients)
386 Temp = zr2 * zr - zi2 * zi + C;
387 zi2 = zr2 * zi + zi2 * zr;
393 foreach (
double C
in Prim)
395 Temp = zr3 * zr - zi3 * zi + C;
396 zi3 = zr3 * zi + zi3 * zr;
402 foreach (
double C
in Bis)
404 Temp = zr4 * zr - zi4 * zi + C;
405 zi4 = zr4 * zi + zi4 * zr;
411 zr5 = 2 * (zr2 * zr3 - zi2 * zi3);
412 zi5 = 2 * (zr2 * zi3 + zi2 * zr3);
416 zr6 = 2 * (zr3 * zr3 - zi3 * zi3) - (zr2 * zr4 - zi2 * zi4);
417 zi6 = 4 * zr3 * zi3 - (zr2 * zi4 + zr4 * zi2);
421 Temp = 1.0 / (zr6 * zr6 + zi6 * zi6);
422 zr4 = (zr5 * zr6 + zi5 * zi6) * Temp;
423 zi4 = (zi5 * zr6 - zr5 * zi6) * Temp;
426 Temp = zr4 * RRe - zi4 * RIm;
427 zi4 = zr4 * RIm + zi4 * RRe;
433 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
435 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
437 if (Temp < Conv && n < N)
438 ColorIndex[index++] = n;
440 ColorIndex[index++] = N;
456 public static async Task<FractalGraph>
CalcHalley(
double rCenter,
double iCenter,
double rDelta, Complex R,
458 FractalZoomScript FractalZoomScript,
object State)
461 double RIm = R.Imaginary;
462 double r0, i0, r1, i1;
465 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4, zr5, zi5, zr6, zi6;
471 int Degree = Coefficients.Length - 1;
477 Array.Resize(ref Coefficients, 4);
479 Coefficients[++Degree] = Complex.Zero;
482 Complex[] Prim =
new Complex[Degree];
483 for (x = 1; x <= Degree; x++)
484 Prim[x - 1] = x * Coefficients[x];
486 Complex[] Bis =
new Complex[Degree - 1];
487 for (x = 1; x < Degree; x++)
488 Bis[x - 1] = x * Prim[x];
492 Coefficients = (Complex[])Coefficients.Clone();
493 Array.Reverse(Coefficients);
495 int j, c = Prim.Length;
497 double[] ReC =
new double[c + 1];
498 double[] ImC =
new double[c + 1];
499 double[] RePrim =
new double[c];
500 double[] ImPrim =
new double[c];
501 double[] ReBis =
new double[c2];
502 double[] ImBis =
new double[c2];
505 for (j = 0; j < c; j++)
509 ImC[j] = z.Imaginary;
513 ImPrim[j] = z.Imaginary;
519 ImBis[j] = z.Imaginary;
525 ImC[j] = z.Imaginary;
527 int size = Width * Height;
528 double[] ColorIndex =
new double[size];
533 r0 = rCenter - rDelta;
534 r1 = rCenter + rDelta;
536 aspect = ((double)Width) / Height;
538 i0 = iCenter - rDelta / aspect;
539 i1 = iCenter + rDelta / aspect;
541 dr = (r1 - r0) / Width;
542 di = (i1 - i0) / Height;
544 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
546 for (x = 0, r = r0; x < Width; x++, r += dr)
556 for (j = 0; j <= c; j++)
558 Temp = zr2 * zr - zi2 * zi + ReC[j];
559 zi2 = zr2 * zi + zi2 * zr + ImC[j];
565 for (j = 0; j < c; j++)
567 Temp = zr3 * zr - zi3 * zi + RePrim[j];
568 zi3 = zr3 * zi + zi3 * zr + ImPrim[j];
574 for (j = 0; j < c2; j++)
576 Temp = zr4 * zr - zi4 * zi + ReBis[j];
577 zi4 = zr4 * zi + zi4 * zr + ImBis[j];
583 zr5 = 2 * (zr2 * zr3 - zi2 * zi3);
584 zi5 = 2 * (zr2 * zi3 + zi2 * zr3);
588 zr6 = 2 * (zr3 * zr3 - zi3 * zi3) - (zr2 * zr4 - zi2 * zi4);
589 zi6 = 4 * zr3 * zi3 - (zr2 * zi4 + zr4 * zi2);
593 Temp = 1.0 / (zr6 * zr6 + zi6 * zi6);
594 zr4 = (zr5 * zr6 + zi5 * zi6) * Temp;
595 zi4 = (zi5 * zr6 - zr5 * zi6) * Temp;
598 Temp = zr4 * RRe - zi4 * RIm;
599 zi4 = zr4 * RIm + zi4 * RRe;
605 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
607 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
609 if (Temp < Conv && n < N)
610 ColorIndex[index++] = n;
612 ColorIndex[index++] = N;
628 public static async Task<FractalGraph>
CalcHalley(
double rCenter,
double iCenter,
double rDelta, Complex R,
630 ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
633 double RIm = R.Imaginary;
634 double r0, i0, r1, i1;
646 string ParameterName;
648 !(Differentiable.Differentiate(ParameterName = Differentiable.DefaultVariableName, v) is
ILambdaExpression fPrim))
659 int size = Width * Height;
660 double[] ColorIndex =
new double[size];
677 r0 = rCenter - rDelta;
678 r1 = rCenter + rDelta;
680 aspect = ((double)Width) / Height;
682 i0 = iCenter - rDelta / aspect;
683 i1 = iCenter + rDelta / aspect;
685 dr = (r1 - r0) / Width;
686 di = (i1 - i0) / Height;
688 for (y = 0, i = i0; y < Height; y++, i += di)
690 Row =
new Complex[Width];
691 Offset =
new int[Width];
694 for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++)
696 Row[x] =
new Complex(r, i);
701 while (n < N && c > 0)
706 Obj2 = fPrim.Evaluate(P, v);
707 Obj3 = fBis.Evaluate(P, v);
708 Row2 = Obj.AssociatedObjectValue as Complex[];
709 Row3 = Obj2.AssociatedObjectValue as Complex[];
710 Row4 = Obj3.AssociatedObjectValue as Complex[];
712 if (Row2 is
null || Row3 is
null || Row4 is
null)
714 throw new ScriptRuntimeException(
"Lambda expression (and its first and second derivative) must be able to accept complex vectors, " +
715 "and return complex vectors of equal length. Type returned: " +
716 Obj.GetType().FullName +
", " + Obj2.GetType().FullName +
" and " + Obj3.GetType().FullName,
719 else if (Row2.Length != c || Row3.Length != c)
721 throw new ScriptRuntimeException(
"Lambda expression (and its first and second derivative) must be able to accept complex vectors, " +
722 "and return complex vectors of equal length. Length returned: " +
723 Row2.Length.ToString() +
", " + Row3.Length.ToString() +
" and " + Row4.Length.ToString() +
724 ". Expected: " + c.ToString(), Node);
727 for (x = x2 = 0; x < c; x++)
734 z = R2 * z * z2 / (2 * z2 * z2 - z * z3);
739 if (Mod > Conv && Mod < Div)
757 Array.Resize(ref Row, x2);
758 Array.Resize(ref Offset, x2);
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 Halley Smooth Fractal Image
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
TODO
HalleySmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode Coefficients, ScriptNode Palette, int Start, int Length, Expression Expression)
TODO
HalleySmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode Coefficients, int Start, int Length, Expression Expression)
TODO
static async Task< FractalGraph > CalcHalley(double rCenter, double iCenter, double rDelta, Complex R, ILambdaExpression f, Variables Variables, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
static async Task< FractalGraph > CalcHalley(double rCenter, double iCenter, double rDelta, Complex R, Complex[] Coefficients, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
HalleySmoothFractal(ScriptNode z, ScriptNode dr, int Start, int Length, Expression Expression)
TODO
override string[] DefaultArgumentNames
TODO
HalleySmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, int Start, int Length, Expression Expression)
TODO
HalleySmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode Coefficients, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
static async Task< FractalGraph > CalcHalley(double rCenter, double iCenter, double rDelta, Complex R, double[] Coefficients, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State)
TODO
HalleySmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode Coefficients, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
override string FunctionName
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
Exception thrown if an image with invalid size is requested.
Defines a clickable fractal graph in the complex plane.
static async Task Smooth(double[] ColorIndex, double[] Boundary, int Width, int Height, int N, SKColor[] Palette, ScriptNode Node, Variables Variables)
TODO
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
Handles bitmap-based graphs.
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.
async Task Preview(Expression Expression, IElement Result)
Reports a preview of the final result.
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.