2using System.Collections.Generic;
45 : base(new
ScriptNode[] { z, dr, R, c, N, DimX, DimY },
57 : base(new
ScriptNode[] { z, dr, R, c, N, DimX },
83 ArgumentType.Normal },
95 return new string[] {
"z",
"dr",
"R",
"c",
"N",
"DimX",
"DimY" };
104 double[] Coefficients =
null;
105 Complex[] CoefficientsZ =
null;
117 Obj =
Arguments[i++].AssociatedObjectValue;
118 if (Obj is Complex z)
134 if (i < c && ((Obj =
Arguments[i].AssociatedObjectValue) is
double || Obj is Complex))
143 if (i < c && this.Arguments[i] is
null)
150 Coefficients = (
double[])
Arguments[i++].AssociatedObjectValue;
152 CoefficientsZ = (Complex[])
Arguments[i++].AssociatedObjectValue;
162 CoefficientsZ =
new Complex[d];
163 for (j = 0; j < d; j++)
170 throw new ScriptRuntimeException(
"Lambda expression in calls to NewtonBasinFractal() must be of one variable.",
this);
172 fDef = this.Arguments[i++];
177 " in call to NewtonBasinFractal has to be a vector of numbers, containing coefficients " +
178 "of the polynomial to use. Now it was of type " +
Arguments[i].GetType().FullName,
202 throw new ScriptRuntimeException(
"Parameter mismatch in call to NewtonBasinFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
206 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
211 return CalcNewton(rc, ic, dr, R, f, fDef,
Variables, N, dimx, dimy,
this, this.FractalZoomScript,
212 new object[] { dimx, dimy, N, R, fDef });
214 else if (!(CoefficientsZ is
null))
216 return CalcNewton(
Variables, rc, ic, dr, R, CoefficientsZ, N, dimx, dimy,
this, this.FractalZoomScript,
217 new object[] { dimx, dimy, N, R, CoefficientsZ });
221 return CalcNewton(
Variables, rc, ic, dr, R, Coefficients, N, dimx, dimy,
this, this.FractalZoomScript,
222 new object[] { dimx, dimy, N, R, Coefficients });
226 private string FractalZoomScript(
double r,
double i,
double Size,
object State)
228 object[] Parameters = (
object[])State;
229 int DimX = (int)Parameters[0];
230 int DimY = (int)Parameters[1];
231 int N = (int)Parameters[2];
232 Complex R = (Complex)Parameters[3];
233 double[] Coefficients = Parameters[4] as
double[];
235 StringBuilder sb =
new StringBuilder();
237 sb.Append(
"NewtonBasinFractal((");
248 sb.Append(fDef.SubExpression);
249 else if (Parameters[4] is Complex[] CoefficientsZ)
255 sb.Append(N.ToString());
257 sb.Append(DimX.ToString());
259 sb.Append(DimY.ToString());
262 return sb.ToString();
269 double[] Coefficients,
int N,
int Width,
int Height,
ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
272 double RIm = R.Imaginary;
273 List<double> AttractorsR =
new List<double>();
274 List<double> AttractorsI =
new List<double>();
275 List<int> AttractorColors =
new List<int>();
276 double[] AttractorsR2 =
new double[0];
277 double[] AttractorsI2 =
new double[0];
278 int[] AttractorsColors2 =
new int[0];
279 double r0, i0, r1, i1;
282 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
285 int x, y, b, c = 0, d;
288 int Degree = Coefficients.Length - 1;
292 Array.Resize(ref Coefficients, 3);
294 Coefficients[++Degree] = 0;
297 double[] Prim =
new double[Degree];
298 for (x = 1; x <= Degree; x++)
299 Prim[x - 1] = x * Coefficients[x];
302 Coefficients = (
double[])Coefficients.Clone();
303 Array.Reverse(Coefficients);
305 int size = Width * Height * 4;
308 double Conv2 = Conv * 2;
309 byte[] rgb =
new byte[size];
312 r0 = rCenter - rDelta;
313 r1 = rCenter + rDelta;
315 aspect = ((double)Width) / Height;
317 i0 = iCenter - rDelta / aspect;
318 i1 = iCenter + rDelta / aspect;
320 dr = (r1 - r0) / Width;
321 di = (i1 - i0) / Height;
323 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
325 for (x = 0, r = r0; x < Width; x++, r += dr)
335 foreach (
double C
in Coefficients)
337 Temp = zr2 * zr - zi2 * zi + C;
338 zi2 = zr2 * zi + zi2 * zr;
344 foreach (
double C
in Prim)
346 Temp = zr3 * zr - zi3 * zi + C;
347 zi3 = zr3 * zi + zi3 * zr;
353 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
354 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
355 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
358 Temp = zr4 * RRe - zi4 * RIm;
359 zi4 = zr4 * RIm + zi4 * RRe;
365 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
367 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
369 if (Temp < Conv && n < N)
371 for (b = 0; b < c; b++)
373 if (Math.Abs(AttractorsR2[b] - zr) < Conv2 &&
374 Math.Abs(AttractorsI2[b] - zi) < Conv2)
385 int p1 = ~((b % 6) + 1);
386 int p2 = ((b / 6) % 7);
388 int Red = (p1 & 1) != 0 ? 255 : 0;
389 int Green = (p1 & 2) != 0 ? 255 : 0;
390 int Blue = (p1 & 4) != 0 ? 255 : 0;
406 AttractorColors.Add(Blue);
408 AttractorsR2 = AttractorsR.ToArray();
409 AttractorsI2 = AttractorsI.ToArray();
410 AttractorsColors2 = AttractorColors.ToArray();
415 b = AttractorColors[b];
418 rgb[index++] = (byte)((d * (N - n + 1)) / N);
421 rgb[index++] = (byte)((d * (N - n + 1)) / N);
424 rgb[index++] = (byte)((d * (N - n + 1)) / N);
438 return new FractalGraph(
Variables, Pixels, r0, i0, r1, i1, rDelta * 2,
true, Node,
FractalZoomScript, State);
445 Complex[] Coefficients,
int N,
int Width,
int Height,
ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
448 double RIm = R.Imaginary;
449 List<double> AttractorsR =
new List<double>();
450 List<double> AttractorsI =
new List<double>();
451 List<int> AttractorColors =
new List<int>();
452 double[] AttractorsR2 =
new double[0];
453 double[] AttractorsI2 =
new double[0];
454 int[] AttractorsColors2 =
new int[0];
455 double r0, i0, r1, i1;
458 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
461 int x, y, b, c = 0, d;
464 int Degree = Coefficients.Length - 1;
468 Array.Resize(ref Coefficients, 3);
470 Coefficients[++Degree] = Complex.Zero;
473 Complex[] Prim =
new Complex[Degree];
474 for (x = 1; x <= Degree; x++)
475 Prim[x - 1] = x * Coefficients[x];
478 Coefficients = (Complex[])Coefficients.Clone();
479 Array.Reverse(Coefficients);
481 int j, e = Prim.Length;
482 double[] ReC =
new double[e + 1];
483 double[] ImC =
new double[e + 1];
484 double[] RePrim =
new double[e];
485 double[] ImPrim =
new double[e];
488 for (j = 0; j < e; j++)
492 ImC[j] = z.Imaginary;
496 ImPrim[j] = z.Imaginary;
501 ImC[j] = z.Imaginary;
503 int size = Width * Height * 4;
506 double Conv2 = Conv * 2;
507 byte[] rgb =
new byte[size];
510 r0 = rCenter - rDelta;
511 r1 = rCenter + rDelta;
513 aspect = ((double)Width) / Height;
515 i0 = iCenter - rDelta / aspect;
516 i1 = iCenter + rDelta / aspect;
518 dr = (r1 - r0) / Width;
519 di = (i1 - i0) / Height;
521 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
523 for (x = 0, r = r0; x < Width; x++, r += dr)
533 for (j = 0; j <= e; j++)
535 Temp = zr2 * zr - zi2 * zi + ReC[j];
536 zi2 = zr2 * zi + zi2 * zr + ImC[j];
542 for (j = 0; j < e; j++)
544 Temp = zr3 * zr - zi3 * zi + RePrim[j];
545 zi3 = zr3 * zi + zi3 * zr + ImPrim[j];
551 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
552 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
553 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
556 Temp = zr4 * RRe - zi4 * RIm;
557 zi4 = zr4 * RIm + zi4 * RRe;
563 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
565 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
567 if (Temp < Conv && n < N)
569 for (b = 0; b < c; b++)
571 if (Math.Abs(AttractorsR2[b] - zr) < Conv2 &&
572 Math.Abs(AttractorsI2[b] - zi) < Conv2)
583 int p1 = ~((b % 6) + 1);
584 int p2 = ((b / 6) % 7);
586 int Red = (p1 & 1) != 0 ? 255 : 0;
587 int Green = (p1 & 2) != 0 ? 255 : 0;
588 int Blue = (p1 & 4) != 0 ? 255 : 0;
604 AttractorColors.Add(Blue);
606 AttractorsR2 = AttractorsR.ToArray();
607 AttractorsI2 = AttractorsI.ToArray();
608 AttractorsColors2 = AttractorColors.ToArray();
613 b = AttractorColors[b];
616 rgb[index++] = (byte)((d * (N - n + 1)) / N);
619 rgb[index++] = (byte)((d * (N - n + 1)) / N);
622 rgb[index++] = (byte)((d * (N - n + 1)) / N);
636 return new FractalGraph(
Variables, Pixels, r0, i0, r1, i1, rDelta * 2,
true, Node,
FractalZoomScript, State);
644 ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
647 double RIm = R.Imaginary;
648 List<double> AttractorsR =
new List<double>();
649 List<double> AttractorsI =
new List<double>();
650 List<int> AttractorColors =
new List<int>();
651 double[] AttractorsR2 =
new double[0];
652 double[] AttractorsI2 =
new double[0];
653 int[] AttractorsColors2 =
new int[0];
654 double r0, i0, r1, i1;
660 int NrAttractors = 0;
668 !(Differentiable.Differentiate(Differentiable.DefaultVariableName, v) is
ILambdaExpression fPrim))
673 int size = Width * Height * 4;
676 double Conv2 = Conv * 2;
677 byte[] rgb =
new byte[size];
690 r0 = rCenter - rDelta;
691 r1 = rCenter + rDelta;
693 aspect = ((double)Width) / Height;
695 i0 = iCenter - rDelta / aspect;
696 i1 = iCenter + rDelta / aspect;
698 dr = (r1 - r0) / Width;
699 di = (i1 - i0) / Height;
701 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
703 Row =
new Complex[Width];
704 Offset =
new int[Width];
707 for (x = 0, x2 = y * Width * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
709 Row[x] =
new Complex(r, i);
714 while (n < N && c > 0)
719 Obj2 = fPrim.Evaluate(P, v);
720 Row2 = Obj.AssociatedObjectValue as Complex[];
721 Row3 = Obj2.AssociatedObjectValue as Complex[];
723 if (Row2 is
null || Row3 is
null)
725 throw new ScriptRuntimeException(
"Lambda expression (and its first derivative) must be able to accept complex vectors, " +
726 "and return complex vectors of equal length. Type returned: " +
727 Obj.GetType().FullName +
" and " + Obj2.GetType().FullName, Node);
729 else if (Row2.Length != c || Row3.Length != c)
731 throw new ScriptRuntimeException(
"Lambda expression (and its first derivative) must be able to accept complex vectors, " +
732 "and return complex vectors of equal length. Length returned: " +
733 Row2.Length.ToString() +
" and " + Row3.Length.ToString() +
734 ". Expected: " + c.ToString(), Node);
737 for (x = x2 = 0; x < c; x++)
740 z = R * Row2[x] / Row3[x];
745 if (Mod > Conv && Mod < Div)
765 for (b = 0; b < NrAttractors; b++)
767 if (Math.Abs(AttractorsR2[b] - zr) < Conv2 &&
768 Math.Abs(AttractorsI2[b] - zi) < Conv2)
774 if (b == NrAttractors)
779 int p1 = ~((b % 6) + 1);
780 int p2 = ((b / 6) % 7);
782 int Red = (p1 & 1) != 0 ? 255 : 0;
783 int Green = (p1 & 2) != 0 ? 255 : 0;
784 int Blue = (p1 & 4) != 0 ? 255 : 0;
800 AttractorColors.Add(Blue);
802 AttractorsR2 = AttractorsR.ToArray();
803 AttractorsI2 = AttractorsI.ToArray();
804 AttractorsColors2 = AttractorColors.ToArray();
809 b = AttractorColors[b];
812 rgb[index++] = (byte)((d * (N - n + 1)) / N);
815 rgb[index++] = (byte)((d * (N - n + 1)) / N);
818 rgb[index++] = (byte)((d * (N - n + 1)) / N);
827 Array.Resize(ref Row, x2);
828 Array.Resize(ref Offset, x2);
836 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 Basin Fractal Image
NewtonBasinFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode N, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
NewtonBasinFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, int Start, int Length, Expression Expression)
TODO
static FractalGraph CalcNewton(Variables Variables, double rCenter, double iCenter, double rDelta, Complex R, double[] Coefficients, int N, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
NewtonBasinFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode N, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
static FractalGraph CalcNewton(double rCenter, double iCenter, double rDelta, Complex R, ILambdaExpression f, ScriptNode _, Variables Variables, int N, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
override string[] DefaultArgumentNames
TODO
static FractalGraph CalcNewton(Variables Variables, double rCenter, double iCenter, double rDelta, Complex R, Complex[] Coefficients, int N, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
TODO
NewtonBasinFractal(ScriptNode z, ScriptNode dr, ScriptNode R, ScriptNode c, ScriptNode N, int Start, int Length, Expression Expression)
TODO
override string FunctionName
TODO
Defines a clickable fractal graph in the complex plane.
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.