4using System.Threading.Tasks;
57 : base(new
ScriptNode[] { z, dr, R, c, Palette, DimX, DimY },
69 : base(new
ScriptNode[] { z, dr, R, c, Palette, DimX },
81 : base(new
ScriptNode[] { z, dr, R, c, Palette },
95 ArgumentType.Normal },
107 return new string[] {
"z",
"dr",
"R",
"c",
"Palette",
"DimX",
"DimY" };
130 string ColorExpression =
null;
132 double[] Coefficients =
null;
133 Complex[] CoefficientsZ =
null;
144 Obj =
Arguments[i++].AssociatedObjectValue;
145 if (Obj is Complex z)
161 if (i < c && ((Obj =
Arguments[i].AssociatedObjectValue) is
double || Obj is Complex))
170 if (i < c && this.Arguments[i] is
null)
177 Coefficients = (
double[])
Arguments[i++].AssociatedObjectValue;
179 CoefficientsZ = (Complex[])
Arguments[i++].AssociatedObjectValue;
189 CoefficientsZ =
new Complex[d];
190 for (j = 0; j < d; j++)
197 throw new ScriptRuntimeException(
"Lambda expression in calls to NewtonSmoothFractal() must be of one variable.",
this);
199 fDef = this.Arguments[i++];
204 " in call to NewtonSmoothFractal has to be a vector of numbers, containing coefficients " +
205 "of the polynomial to use. Now it was of type " +
Arguments[i].GetType().FullName,
214 ColorExpression = this.Arguments[i].SubExpression;
219 Palette = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out
int Seed,
this,
Variables);
220 ColorExpression =
"RandomLinearAnalogousHSL(128,4," + Seed.ToString() +
")";
222 if (i < c && this.Arguments[i] is
null)
238 throw new ScriptRuntimeException(
"Parameter mismatch in call to NewtonSmoothFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
242 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
247 return await
CalcNewtonSmooth(rc, ic, dr, R, f,
Variables, Palette, dimx, dimy,
this, this.FractalZoomScript,
248 new object[] { Palette, dimx, dimy, R, fDef, ColorExpression });
250 else if (!(CoefficientsZ is
null))
252 return await
CalcNewtonSmooth(rc, ic, dr, R, CoefficientsZ, Palette, dimx, dimy,
254 new object[] { Palette, dimx, dimy, R, CoefficientsZ, ColorExpression });
258 return await
CalcNewtonSmooth(rc, ic, dr, R, Coefficients, Palette, dimx, dimy,
260 new object[] { Palette, dimx, dimy, R, Coefficients, ColorExpression });
264 private string FractalZoomScript(
double r,
double i,
double Size,
object State)
266 object[] Parameters = (
object[])State;
267 int DimX = (int)Parameters[1];
268 int DimY = (int)Parameters[2];
269 Complex R = (Complex)Parameters[3];
270 double[] Coefficients = Parameters[4] as
double[];
271 string ColorExpression = (string)Parameters[5];
273 StringBuilder sb =
new StringBuilder();
275 sb.Append(
"NewtonSmoothFractal((");
286 sb.Append(fDef.SubExpression);
287 else if (Parameters[4] is Complex[] CoefficientsZ)
292 if (!
string.IsNullOrEmpty(ColorExpression))
295 sb.Append(ColorExpression);
299 sb.Append(DimX.ToString());
301 sb.Append(DimY.ToString());
304 return sb.ToString();
310 public static async Task<FractalGraph>
CalcNewtonSmooth(
double rCenter,
double iCenter,
double rDelta, Complex R,
312 FractalZoomScript FractalZoomScript,
object State)
315 double RIm = R.Imaginary;
316 double r0, i0, r1, i1;
319 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
324 int Degree = Coefficients.Length - 1;
330 Array.Resize(ref Coefficients, 3);
332 Coefficients[++Degree] = 0;
335 if (Width <= 2 || Height <= 2)
338 double[] Prim =
new double[Degree];
339 for (x = 1; x <= Degree; x++)
340 Prim[x - 1] = x * Coefficients[x];
343 Coefficients = (
double[])Coefficients.Clone();
344 Array.Reverse(Coefficients);
346 int Size = Width * Height;
349 double[] ColorIndex =
new double[Size];
353 r0 = rCenter - rDelta;
354 r1 = rCenter + rDelta;
356 aspect = ((double)Width) / Height;
358 i0 = iCenter - rDelta / aspect;
359 i1 = iCenter + rDelta / aspect;
361 dr = (r1 - r0) / Width;
362 di = (i1 - i0) / Height;
364 for (y = 0, i = i0; y < Height; y++, i += di)
366 for (x = 0, r = r0; x < Width; x++, r += dr)
376 foreach (
double C
in Coefficients)
378 Temp = zr2 * zr - zi2 * zi + C;
379 zi2 = zr2 * zi + zi2 * zr;
385 foreach (
double C
in Prim)
387 Temp = zr3 * zr - zi3 * zi + C;
388 zi3 = zr3 * zi + zi3 * zr;
394 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
395 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
396 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
399 Temp = zr4 * RRe - zi4 * RIm;
400 zi4 = zr4 * RIm + zi4 * RRe;
406 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
408 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
410 if (Temp < Conv && n < N)
411 ColorIndex[Index++] = n;
413 ColorIndex[Index++] = N;
429 public static async Task<FractalGraph>
CalcNewtonSmooth(
double rCenter,
double iCenter,
double rDelta, Complex R,
431 FractalZoomScript FractalZoomScript,
object State)
434 double RIm = R.Imaginary;
435 double r0, i0, r1, i1;
438 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
443 int Degree = Coefficients.Length - 1;
449 Array.Resize(ref Coefficients, 3);
451 Coefficients[++Degree] = Complex.Zero;
454 if (Width <= 2 || Height <= 2)
457 Complex[] Prim =
new Complex[Degree];
458 for (x = 1; x <= Degree; x++)
459 Prim[x - 1] = x * Coefficients[x];
462 Coefficients = (Complex[])Coefficients.Clone();
463 Array.Reverse(Coefficients);
465 int j, c = Prim.Length;
466 double[] ReC =
new double[c + 1];
467 double[] ImC =
new double[c + 1];
468 double[] RePrim =
new double[c];
469 double[] ImPrim =
new double[c];
472 for (j = 0; j < c; j++)
476 ImC[j] = z.Imaginary;
480 ImPrim[j] = z.Imaginary;
485 ImC[j] = z.Imaginary;
487 int Size = Width * Height;
490 double[] ColorIndex =
new double[Size];
494 r0 = rCenter - rDelta;
495 r1 = rCenter + rDelta;
497 aspect = ((double)Width) / Height;
499 i0 = iCenter - rDelta / aspect;
500 i1 = iCenter + rDelta / aspect;
502 dr = (r1 - r0) / Width;
503 di = (i1 - i0) / Height;
505 for (y = 0, i = i0; y < Height; y++, i += di)
507 for (x = 0, r = r0; x < Width; x++, r += dr)
517 for (j = 0; j <= c; j++)
519 Temp = zr2 * zr - zi2 * zi + ReC[j];
520 zi2 = zr2 * zi + zi2 * zr + ImC[j];
526 for (j = 0; j < c; j++)
528 Temp = zr3 * zr - zi3 * zi + RePrim[j];
529 zi3 = zr3 * zi + zi3 * zr + ImPrim[j];
535 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
536 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
537 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
540 Temp = zr4 * RRe - zi4 * RIm;
541 zi4 = zr4 * RIm + zi4 * RRe;
547 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
549 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
551 if (Temp < Conv && n < N)
552 ColorIndex[Index++] = n;
554 ColorIndex[Index++] = N;
570 public static async Task<FractalGraph>
CalcNewtonSmooth(
double rCenter,
double iCenter,
double rDelta, Complex R,
572 ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
575 double RIm = R.Imaginary;
576 double r0, i0, r1, i1;
585 if (Width <= 2 || Height <= 2)
592 !(Differentiable.Differentiate(Differentiable.DefaultVariableName, v) is
ILambdaExpression fPrim))
597 int Size = Width * Height;
600 double[] ColorIndex =
new double[Size];
614 r0 = rCenter - rDelta;
615 r1 = rCenter + rDelta;
617 aspect = ((double)Width) / Height;
619 i0 = iCenter - rDelta / aspect;
620 i1 = iCenter + rDelta / aspect;
622 dr = (r1 - r0) / Width;
623 di = (i1 - i0) / Height;
625 for (y = 0, i = i0; y < Height; y++, i += di)
627 Row =
new Complex[Width];
628 Offset =
new int[Width];
631 for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++)
633 Row[x] =
new Complex(r, i);
638 while (n < N && c > 0)
643 Obj2 = fPrim.Evaluate(P, v);
644 Row2 = Obj.AssociatedObjectValue as Complex[];
645 Row3 = Obj2.AssociatedObjectValue as Complex[];
647 if (Row2 is
null || Row3 is
null)
649 throw new ScriptRuntimeException(
"Lambda expression (and its first derivative) must be able to accept complex vectors, " +
650 "and return complex vectors of equal length. Type returned: " +
651 Obj.GetType().FullName +
" and " + Obj2.GetType().FullName, Node);
653 else if (Row2.Length != c || Row3.Length != c)
655 throw new ScriptRuntimeException(
"Lambda expression (and its first derivative) must be able to accept complex vectors, " +
656 "and return complex vectors of equal length. Length returned: " +
657 Row2.Length.ToString() +
" and " + Row3.Length.ToString() +
658 ". Expected: " + c.ToString(), Node);
661 for (x = x2 = 0; x < c; x++)
664 z = R * Row2[x] / Row3[x];
669 if (Mod > Conv && Mod < Div)
679 ColorIndex[Index++] = N;
687 Array.Resize(ref Row, x2);
688 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 Newton Fractal Image, and smoothes the colors using the heat equation in two spatial dim...
NewtonSmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode Palette, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
static async Task< FractalGraph > CalcNewtonSmooth(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
NewtonSmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, int Start, int Length, Expression Expression)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
static async Task< FractalGraph > CalcNewtonSmooth(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
static async Task< FractalGraph > CalcNewtonSmooth(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
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
override string FunctionName
TODO
NewtonSmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode Palette, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
override string[] DefaultArgumentNames
TODO
override async Task< IElement > EvaluateAsync(IElement[] Arguments, Variables Variables)
TODO
NewtonSmoothFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode Palette, 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.
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.