46 : base(new
ScriptNode[] { z, dr, R, c, N, DimX, DimY },
58 : base(new
ScriptNode[] { z, dr, R, c, N, DimX },
84 ArgumentType.Normal },
96 return new string[] {
"z",
"dr",
"R",
"c",
"N",
"DimX",
"DimY" };
105 double[] Coefficients =
null;
106 Complex[] CoefficientsZ =
null;
118 Obj =
Arguments[i++].AssociatedObjectValue;
119 if (Obj is Complex z)
135 if (i < c && ((Obj =
Arguments[i].AssociatedObjectValue) is
double || Obj is Complex))
144 if (i < c && this.Arguments[i] is
null)
151 Coefficients = (
double[])
Arguments[i++].AssociatedObjectValue;
153 CoefficientsZ = (Complex[])
Arguments[i++].AssociatedObjectValue;
163 CoefficientsZ =
new Complex[d];
164 for (j = 0; j < d; j++)
171 throw new ScriptRuntimeException(
"Lambda expression in calls to NewtonBasinFractal() must be of one variable.",
this);
173 fDef = this.Arguments[i++];
178 " in call to NewtonBasinFractal has to be a vector of numbers, containing coefficients " +
179 "of the polynomial to use. Now it was of type " +
Arguments[i].GetType().FullName,
203 throw new ScriptRuntimeException(
"Parameter mismatch in call to NewtonBasinFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
207 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
212 return CalcNewton(rc, ic, dr, R, f, fDef,
Variables, N, dimx, dimy,
this, this.FractalZoomScript,
213 new object[] { dimx, dimy, N, R, fDef });
215 else if (!(CoefficientsZ is
null))
217 return CalcNewton(
Variables, rc, ic, dr, R, CoefficientsZ, N, dimx, dimy,
this, this.FractalZoomScript,
218 new object[] { dimx, dimy, N, R, CoefficientsZ });
222 return CalcNewton(
Variables, rc, ic, dr, R, Coefficients, N, dimx, dimy,
this, this.FractalZoomScript,
223 new object[] { dimx, dimy, N, R, Coefficients });
227 private string FractalZoomScript(
double r,
double i,
double Size,
object State)
229 object[] Parameters = (
object[])State;
230 int DimX = (int)Parameters[0];
231 int DimY = (int)Parameters[1];
232 int N = (int)Parameters[2];
233 Complex R = (Complex)Parameters[3];
234 double[] Coefficients = Parameters[4] as
double[];
236 StringBuilder sb =
new StringBuilder();
238 sb.Append(
"NewtonBasinFractal((");
249 sb.Append(fDef.SubExpression);
250 else if (Parameters[4] is Complex[] CoefficientsZ)
256 sb.Append(N.ToString());
258 sb.Append(DimX.ToString());
260 sb.Append(DimY.ToString());
263 return sb.ToString();
270 double[] Coefficients,
int N,
int Width,
int Height,
ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
273 double RIm = R.Imaginary;
277 double[] AttractorsR2 = Array.Empty<
double>();
278 double[] AttractorsI2 = Array.Empty<
double>();
279 int[] AttractorsColors2 = Array.Empty<
int>();
280 double r0, i0, r1, i1;
283 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
286 int x, y, b, c = 0, d;
289 int Degree = Coefficients.Length - 1;
293 Array.Resize(ref Coefficients, 3);
295 Coefficients[++Degree] = 0;
298 double[] Prim =
new double[Degree];
299 for (x = 1; x <= Degree; x++)
300 Prim[x - 1] = x * Coefficients[x];
303 Coefficients = (
double[])Coefficients.Clone();
304 Array.Reverse(Coefficients);
306 int size = Width * Height * 4;
309 double Conv2 = Conv * 2;
310 byte[] rgb =
new byte[size];
313 r0 = rCenter - rDelta;
314 r1 = rCenter + rDelta;
316 aspect = ((double)Width) / Height;
318 i0 = iCenter - rDelta / aspect;
319 i1 = iCenter + rDelta / aspect;
321 dr = (r1 - r0) / Width;
322 di = (i1 - i0) / Height;
324 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
326 for (x = 0, r = r0; x < Width; x++, r += dr)
336 foreach (
double C
in Coefficients)
338 Temp = zr2 * zr - zi2 * zi + C;
339 zi2 = zr2 * zi + zi2 * zr;
345 foreach (
double C
in Prim)
347 Temp = zr3 * zr - zi3 * zi + C;
348 zi3 = zr3 * zi + zi3 * zr;
354 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
355 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
356 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
359 Temp = zr4 * RRe - zi4 * RIm;
360 zi4 = zr4 * RIm + zi4 * RRe;
366 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
368 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
370 if (Temp < Conv && n < N)
372 for (b = 0; b < c; b++)
374 if (Math.Abs(AttractorsR2[b] - zr) < Conv2 &&
375 Math.Abs(AttractorsI2[b] - zi) < Conv2)
386 int p1 = ~((b % 6) + 1);
387 int p2 = ((b / 6) % 7);
389 int Red = (p1 & 1) != 0 ? 255 : 0;
390 int Green = (p1 & 2) != 0 ? 255 : 0;
391 int Blue = (p1 & 4) != 0 ? 255 : 0;
407 AttractorColors.
Add(Blue);
409 AttractorsR2 = AttractorsR.
ToArray();
410 AttractorsI2 = AttractorsI.
ToArray();
411 AttractorsColors2 = AttractorColors.
ToArray();
416 b = AttractorColors[b];
419 rgb[index++] = (byte)((d * (N - n + 1)) / N);
422 rgb[index++] = (byte)((d * (N - n + 1)) / N);
425 rgb[index++] = (byte)((d * (N - n + 1)) / N);
439 return new FractalGraph(
Variables, Pixels, r0, i0, r1, i1, rDelta * 2,
true, Node,
FractalZoomScript, State);
446 Complex[] Coefficients,
int N,
int Width,
int Height,
ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
449 double RIm = R.Imaginary;
453 double[] AttractorsR2 = Array.Empty<
double>();
454 double[] AttractorsI2 = Array.Empty<
double>();
455 int[] AttractorsColors2 = Array.Empty<
int>();
456 double r0, i0, r1, i1;
459 double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4;
462 int x, y, b, c = 0, d;
465 int Degree = Coefficients.Length - 1;
469 Array.Resize(ref Coefficients, 3);
471 Coefficients[++Degree] = Complex.Zero;
474 Complex[] Prim =
new Complex[Degree];
475 for (x = 1; x <= Degree; x++)
476 Prim[x - 1] = x * Coefficients[x];
479 Coefficients = (Complex[])Coefficients.Clone();
480 Array.Reverse(Coefficients);
482 int j, e = Prim.Length;
483 double[] ReC =
new double[e + 1];
484 double[] ImC =
new double[e + 1];
485 double[] RePrim =
new double[e];
486 double[] ImPrim =
new double[e];
489 for (j = 0; j < e; j++)
493 ImC[j] = z.Imaginary;
497 ImPrim[j] = z.Imaginary;
502 ImC[j] = z.Imaginary;
504 int size = Width * Height * 4;
507 double Conv2 = Conv * 2;
508 byte[] rgb =
new byte[size];
511 r0 = rCenter - rDelta;
512 r1 = rCenter + rDelta;
514 aspect = ((double)Width) / Height;
516 i0 = iCenter - rDelta / aspect;
517 i1 = iCenter + rDelta / aspect;
519 dr = (r1 - r0) / Width;
520 di = (i1 - i0) / Height;
522 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
524 for (x = 0, r = r0; x < Width; x++, r += dr)
534 for (j = 0; j <= e; j++)
536 Temp = zr2 * zr - zi2 * zi + ReC[j];
537 zi2 = zr2 * zi + zi2 * zr + ImC[j];
543 for (j = 0; j < e; j++)
545 Temp = zr3 * zr - zi3 * zi + RePrim[j];
546 zi3 = zr3 * zi + zi3 * zr + ImPrim[j];
552 Temp = 1.0 / (zr3 * zr3 + zi3 * zi3);
553 zr4 = (zr2 * zr3 + zi2 * zi3) * Temp;
554 zi4 = (zi2 * zr3 - zr2 * zi3) * Temp;
557 Temp = zr4 * RRe - zi4 * RIm;
558 zi4 = zr4 * RIm + zi4 * RRe;
564 Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4);
566 while ((Temp > Conv) && (Temp < Div) && (n++ < N));
568 if (Temp < Conv && n < N)
570 for (b = 0; b < c; b++)
572 if (Math.Abs(AttractorsR2[b] - zr) < Conv2 &&
573 Math.Abs(AttractorsI2[b] - zi) < Conv2)
584 int p1 = ~((b % 6) + 1);
585 int p2 = ((b / 6) % 7);
587 int Red = (p1 & 1) != 0 ? 255 : 0;
588 int Green = (p1 & 2) != 0 ? 255 : 0;
589 int Blue = (p1 & 4) != 0 ? 255 : 0;
605 AttractorColors.
Add(Blue);
607 AttractorsR2 = AttractorsR.
ToArray();
608 AttractorsI2 = AttractorsI.
ToArray();
609 AttractorsColors2 = AttractorColors.
ToArray();
614 b = AttractorColors[b];
617 rgb[index++] = (byte)((d * (N - n + 1)) / N);
620 rgb[index++] = (byte)((d * (N - n + 1)) / N);
623 rgb[index++] = (byte)((d * (N - n + 1)) / N);
637 return new FractalGraph(
Variables, Pixels, r0, i0, r1, i1, rDelta * 2,
true, Node,
FractalZoomScript, State);
645 ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
648 double RIm = R.Imaginary;
652 double[] AttractorsR2 = Array.Empty<
double>();
653 double[] AttractorsI2 = Array.Empty<
double>();
654 int[] AttractorsColors2 = Array.Empty<
int>();
655 double r0, i0, r1, i1;
661 int NrAttractors = 0;
669 !(Differentiable.Differentiate(Differentiable.DefaultVariableName, v) is
ILambdaExpression fPrim))
674 int size = Width * Height * 4;
677 double Conv2 = Conv * 2;
678 byte[] rgb =
new byte[size];
691 r0 = rCenter - rDelta;
692 r1 = rCenter + rDelta;
694 aspect = ((double)Width) / Height;
696 i0 = iCenter - rDelta / aspect;
697 i1 = iCenter + rDelta / aspect;
699 dr = (r1 - r0) / Width;
700 di = (i1 - i0) / Height;
702 for (y = 0, i = i0, index = 0; y < Height; y++, i += di)
704 Row =
new Complex[Width];
705 Offset =
new int[Width];
708 for (x = 0, x2 = y * Width * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
710 Row[x] =
new Complex(r, i);
715 while (n < N && c > 0)
720 Obj2 = fPrim.Evaluate(P, v);
721 Row2 = Obj.AssociatedObjectValue as Complex[];
722 Row3 = Obj2.AssociatedObjectValue as Complex[];
724 if (Row2 is
null || Row3 is
null)
726 throw new ScriptRuntimeException(
"Lambda expression (and its first derivative) must be able to accept complex vectors, " +
727 "and return complex vectors of equal length. Type returned: " +
728 Obj.GetType().FullName +
" and " + Obj2.GetType().FullName, Node);
730 else if (Row2.Length != c || Row3.Length != c)
732 throw new ScriptRuntimeException(
"Lambda expression (and its first derivative) must be able to accept complex vectors, " +
733 "and return complex vectors of equal length. Length returned: " +
734 Row2.Length.ToString() +
" and " + Row3.Length.ToString() +
735 ". Expected: " + c.ToString(), Node);
738 for (x = x2 = 0; x < c; x++)
741 z = R * Row2[x] / Row3[x];
746 if (Mod > Conv && Mod < Div)
766 for (b = 0; b < NrAttractors; b++)
768 if (Math.Abs(AttractorsR2[b] - zr) < Conv2 &&
769 Math.Abs(AttractorsI2[b] - zi) < Conv2)
775 if (b == NrAttractors)
780 int p1 = ~((b % 6) + 1);
781 int p2 = ((b / 6) % 7);
783 int Red = (p1 & 1) != 0 ? 255 : 0;
784 int Green = (p1 & 2) != 0 ? 255 : 0;
785 int Blue = (p1 & 4) != 0 ? 255 : 0;
801 AttractorColors.
Add(Blue);
803 AttractorsR2 = AttractorsR.
ToArray();
804 AttractorsI2 = AttractorsI.
ToArray();
805 AttractorsColors2 = AttractorColors.
ToArray();
810 b = AttractorColors[b];
813 rgb[index++] = (byte)((d * (N - n + 1)) / N);
816 rgb[index++] = (byte)((d * (N - n + 1)) / N);
819 rgb[index++] = (byte)((d * (N - n + 1)) / N);
828 Array.Resize(ref Row, x2);
829 Array.Resize(ref Offset, x2);
837 return new FractalGraph(
Variables, Pixels, r0, i0, r1, i1, rDelta * 2,
true, Node,
FractalZoomScript, State);
A chunked list is a linked list of chunks of objects of type T .
void Add(T Item)
Adds an item to the collection.
T[] ToArray()
Returns an array containing all elements of the collection.
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
Exception thrown if an image with invalid size is requested.
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.