public static FractalGraph CalcMandelbrot(double rCenter, double iCenter, double rDelta, ILambdaExpression f, Variables Variables, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { double r0, i0, r1, i1; double dr, di; double r, i, Mod; double aspect; int x, x2, y; int n, N; N = Palette.Length; int Size = Width * Height; int[] ColorIndex = new int[Size]; Complex z; IElement[] P = new IElement[2]; int j, c; IElement Obj; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; for (y = 0, i = i0; y < Height; y++, i += di) { Complex[] Row = new Complex[Width]; Complex[] Row0 = new Complex[Width]; int[] Offset = new int[Width]; c = Width; for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++) { Row[x] = Row0[x] = new Complex(r, i); Offset[x] = x2; } Variables v = new Variables(); Variables.CopyTo(v); n = 0; while (n < N && c > 0) { n++; P[0] = Expression.Encapsulate(Row); P[1] = Expression.Encapsulate(Row0); Obj = f.Evaluate(P, v); Row = Obj.AssociatedObjectValue as Complex[]; if (Row == null) { throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " + "and return complex vectors of equal length. Type returned: " + Obj.GetType().FullName, Node); } else if (Row.Length != c) { throw new ScriptRuntimeException("Lambda expression must be able to accept complex vectors, " + "and return complex vectors of equal length. Length returned: " + Row.Length.ToString() + ". Expected: " + c.ToString(), Node); } for (x = x2 = 0; x < c; x++) { z = Row[x]; j = Offset[x]; Mod = z.Magnitude; if (Mod < 3) { if (x != x2) { Row[x2] = z; Row0[x2] = Row0[x]; Offset[x2] = j; } x2++; } else { if (n >= N) { ColorIndex[j++] = N; } else { ColorIndex[j++] = n; } } } if (x2 < x) { Array.Resize <Complex>(ref Row, x2); Array.Resize <Complex>(ref Row0, x2); Array.Resize <int>(ref Offset, x2); c = x2; } } if (c > 0) { for (x = 0; x < c; x++) { j = Offset[x]; ColorIndex[j] = N; } } } ColorIndex = FractalGraph.FindBoundaries(ColorIndex, Width, Height); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph CalcNova(double rCenter, double iCenter, double rDelta, double Rr, double Ri, double pr, double pi, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { double r0, i0, r1, i1; double dr, di; double r, i; double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4; double aspect; double Temp; int x, y; int n, N; int index; double lnz; double argz; double amp; double phi; N = Palette.Length; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; int Size = Width * Height; int[] ColorIndex = new int[Size]; double Conv = 1e-10; double Div = 1e10; for (y = 0, i = i0, index = 0; y < Height; y++, i += di) { for (x = 0, r = r0; x < Width; x++, r += dr) { zr = r; zi = i; n = 0; do { // f: z->z^p-1 = exp(p*ln(z))-1 // exp(a+ib)=exp(a)*(cos(b)+i*sin(b)) // ln(z)=ln|z|+i*arg(z) // exp(p*ln(z))-1 = // = exp((pr+i*pi)*(ln|z|+i*arg(z)))-1 = // = exp(pr*ln|z|-pi*arg(z)+i*(pi*ln|z|+pr*arg(z)))-1 = // = exp(pr*ln|z|-pi*arg(z))*(cos(pi*ln|z|+pr*arg(z))+i*sin(pi*ln|z|+pr*arg(z)))-1 lnz = System.Math.Log(Math.Sqrt(zr * zr + zi * zi)); argz = System.Math.Atan2(zi, zr); amp = System.Math.Exp(pr * lnz - pi * argz); phi = pi * lnz + pr * argz; zr2 = amp * System.Math.Cos(phi) - 1; zi2 = amp * System.Math.Sin(phi); // f': z->p*z^(p-1) = p*exp((p-1)*ln(z)) = // = (pr+i*pi)*exp((pr-1+i*pi)*(ln|z|+i*arg(z))) = // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z)+i*(pi*ln|z|+(pr-1)*arg(z))) = // = (pr+i*pi)*exp((pr-1)*ln|z|-pi*arg(z))(sin(pi*ln|z|+(pr-1)*arg(z))+i*cos(pi*ln|z|+(pr-1)*arg(z))) = amp = System.Math.Exp((pr - 1) * lnz - pi * argz); phi = pi * lnz + (pr - 1) * argz; zr3 = amp * System.Math.Cos(phi); zi3 = amp * System.Math.Sin(phi); Temp = pr * zr3 - pi * zi3; zi3 = pr * zi3 + pi * zr3; zr3 = Temp; // f/f': Temp = 1.0 / (zr3 * zr3 + zi3 * zi3); zr4 = (zr2 * zr3 + zi2 * zi3) * Temp; zi4 = (zi2 * zr3 - zr2 * zi3) * Temp; Temp = Rr * zr4 - Ri * zi4; zi4 = Ri * zr4 + Rr * zi4; zr4 = Temp; zr -= zr4; zi -= zi4; Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4); }while ((Temp > Conv) && (Temp < Div) && (n++ < N)); if (Temp < Conv && n < N) { ColorIndex[index++] = n; } else { ColorIndex[index++] = N; } } } ColorIndex = FractalGraph.FindBoundaries(ColorIndex, Width, Height); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph CalcMandelbrot(double rCenter, double iCenter, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { double r0, i0, r1, i1; double dr, di; double r, i; double zr, zi, zrt, zr2, zi2; double aspect; int x, y; int n, N; N = Palette.Length; int Size = Width * Height; int[] ColorIndex = new int[Size]; int Index = 0; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; for (y = 0, i = i0; y < Height; y++, i += di) { for (x = 0, r = r0; x < Width; x++, r += dr) { zr = r; zi = i; n = 0; zr2 = zr * zr; zi2 = zi * zi; while (zr2 + zi2 < 9 && n < N) { n++; zrt = zr2 - zi2 + r; zi = 2 * zr * zi + i; zr = zrt; zr2 = zr * zr; zi2 = zi * zi; } if (n >= N) { ColorIndex[Index++] = N; } else { ColorIndex[Index++] = n; } } } ColorIndex = FractalGraph.FindBoundaries(ColorIndex, Width, Height); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph CalcNewtonSmooth(double rCenter, double iCenter, double rDelta, Complex R, ILambdaExpression f, ScriptNode fDef, Variables Variables, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { double RRe = R.Real; double RIm = R.Imaginary; double r0, i0, r1, i1; double dr, di; double r, i; double aspect; int x, y; int n, N; N = Palette.Length; if (Width <= 2 || Height <= 2) { throw new ScriptRuntimeException("Width and Height has to be greater than 2.", Node); } Variables v = new Variables(); Variables.CopyTo(v); if (!(f is IDifferentiable Differentiable) || !(Differentiable.Differentiate(Differentiable.DefaultVariableName, v) is ILambdaExpression fPrim)) { throw new ScriptRuntimeException("Lambda expression not differentiable.", Node); } int Size = Width * Height; double Conv = 1e-10; double Div = 1e10; double[] ColorIndex = new double[Size]; int Index = 0; Complex[] Row; Complex[] Row2; Complex[] Row3; int[] Offset; IElement[] P = new IElement[1]; int j, c, x2; IElement Obj, Obj2; double Mod; Complex z; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; for (y = 0, i = i0; y < Height; y++, i += di) { Row = new Complex[Width]; Offset = new int[Width]; c = Width; for (x = 0, x2 = y * Width, r = r0; x < Width; x++, r += dr, x2++) { Row[x] = new Complex(r, i); Offset[x] = x2; } n = 0; while (n < N && c > 0) { n++; P[0] = Expression.Encapsulate(Row); Obj = f.Evaluate(P, v); Obj2 = fPrim.Evaluate(P, v); Row2 = Obj.AssociatedObjectValue as Complex[]; Row3 = Obj2.AssociatedObjectValue as Complex[]; if (Row2 == null || Row3 == null) { throw new ScriptRuntimeException("Lambda expression (and its first derivative) must be able to accept complex vectors, " + "and return complex vectors of equal length. Type returned: " + Obj.GetType().FullName + " and " + Obj2.GetType().FullName, Node); } else if (Row2.Length != c || Row3.Length != c) { throw new ScriptRuntimeException("Lambda expression (and its first derivative) must be able to accept complex vectors, " + "and return complex vectors of equal length. Length returned: " + Row2.Length.ToString() + " and " + Row3.Length.ToString() + ". Expected: " + c.ToString(), Node); } for (x = x2 = 0; x < c; x++) { j = Offset[x]; z = R * Row2[x] / Row3[x]; Row[x] -= z; Mod = z.Magnitude; if (Mod > Conv && Mod < Div) { if (x != x2) { Offset[x2] = j; } x2++; } else { if (n >= N) { ColorIndex[Index++] = N; } else { ColorIndex[j++] = n; } } } if (x2 < x) { Array.Resize <Complex>(ref Row, x2); Array.Resize <int>(ref Offset, x2); c = x2; } } } Node.Expression.Preview(new GraphBitmap(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette))); double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height); FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static 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) { double RRe = R.Real; double RIm = R.Imaginary; double r0, i0, r1, i1; double dr, di; double r, i; double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4; double aspect; double Temp; int x, y; int n, N; int Degree = Coefficients.Length - 1; N = Palette.Length; if (Degree < 2) { Array.Resize <Complex>(ref Coefficients, 3); while (Degree < 2) { Coefficients[++Degree] = Complex.Zero; } } if (Width <= 2 || Height <= 2) { throw new ScriptRuntimeException("Width and Height has to be greater than 2.", Node); } Complex[] Prim = new Complex[Degree]; for (x = 1; x <= Degree; x++) { Prim[x - 1] = x * Coefficients[x]; } Array.Reverse(Prim); Coefficients = (Complex[])Coefficients.Clone(); Array.Reverse(Coefficients); int j, c = Prim.Length; double[] ReC = new double[c + 1]; double[] ImC = new double[c + 1]; double[] RePrim = new double[c]; double[] ImPrim = new double[c]; Complex z; for (j = 0; j < c; j++) { z = Coefficients[j]; ReC[j] = z.Real; ImC[j] = z.Imaginary; z = Prim[j]; RePrim[j] = z.Real; ImPrim[j] = z.Imaginary; } z = Coefficients[j]; ReC[j] = z.Real; ImC[j] = z.Imaginary; int Size = Width * Height; double Conv = 1e-10; double Div = 1e10; double[] ColorIndex = new double[Size]; int Index = 0; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; for (y = 0, i = i0; y < Height; y++, i += di) { for (x = 0, r = r0; x < Width; x++, r += dr) { zr = r; zi = i; n = 0; do { // f: zr2 = zi2 = 0; for (j = 0; j <= c; j++) { Temp = zr2 * zr - zi2 * zi + ReC[j]; zi2 = zr2 * zi + zi2 * zr + ImC[j]; zr2 = Temp; } // f': zr3 = zi3 = 0; for (j = 0; j < c; j++) { Temp = zr3 * zr - zi3 * zi + RePrim[j]; zi3 = zr3 * zi + zi3 * zr + ImPrim[j]; zr3 = Temp; } // f/f': Temp = 1.0 / (zr3 * zr3 + zi3 * zi3); zr4 = (zr2 * zr3 + zi2 * zi3) * Temp; zi4 = (zi2 * zr3 - zr2 * zi3) * Temp; // R*f/f' Temp = zr4 * RRe - zi4 * RIm; zi4 = zr4 * RIm + zi4 * RRe; zr4 = Temp; zr -= zr4; zi -= zi4; Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4); }while ((Temp > Conv) && (Temp < Div) && (n++ < N)); if (Temp < Conv && n < N) { ColorIndex[Index++] = n; } else { ColorIndex[Index++] = N; } } } Node.Expression.Preview(new GraphBitmap(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette))); double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height); FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph CalcHalley(double rCenter, double iCenter, double rDelta, Complex R, Complex[] Coefficients, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { double RRe = R.Real; double RIm = R.Imaginary; double r0, i0, r1, i1; double dr, di; double r, i; double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4, zr5, zi5, zr6, zi6; double aspect; double Temp; int x, y; int n, N; int index; int Degree = Coefficients.Length - 1; N = Palette.Length; if (Degree < 3) { Array.Resize <Complex>(ref Coefficients, 4); while (Degree < 3) { Coefficients[++Degree] = Complex.Zero; } } Complex[] Prim = new Complex[Degree]; for (x = 1; x <= Degree; x++) { Prim[x - 1] = x * Coefficients[x]; } Complex[] Bis = new Complex[Degree - 1]; for (x = 1; x < Degree; x++) { Bis[x - 1] = x * Prim[x]; } Array.Reverse(Bis); Array.Reverse(Prim); Coefficients = (Complex[])Coefficients.Clone(); Array.Reverse(Coefficients); int j, c = Prim.Length; int c2 = c - 1; double[] ReC = new double[c + 1]; double[] ImC = new double[c + 1]; double[] RePrim = new double[c]; double[] ImPrim = new double[c]; double[] ReBis = new double[c2]; double[] ImBis = new double[c2]; Complex z; for (j = 0; j < c; j++) { z = Coefficients[j]; ReC[j] = z.Real; ImC[j] = z.Imaginary; z = Prim[j]; RePrim[j] = z.Real; ImPrim[j] = z.Imaginary; if (j < c2) { z = Bis[j]; ReBis[j] = z.Real; ImBis[j] = z.Imaginary; } } z = Coefficients[j]; ReC[j] = z.Real; ImC[j] = z.Imaginary; int size = Width * Height; int[] ColorIndex = new int[size]; double Conv = 1e-10; double Div = 1e10; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; for (y = 0, i = i0, index = 0; y < Height; y++, i += di) { for (x = 0, r = r0; x < Width; x++, r += dr) { zr = r; zi = i; n = 0; do { // f: zr2 = zi2 = 0; for (j = 0; j <= c; j++) { Temp = zr2 * zr - zi2 * zi + ReC[j]; zi2 = zr2 * zi + zi2 * zr + ImC[j]; zr2 = Temp; } // f': zr3 = zi3 = 0; for (j = 0; j < c; j++) { Temp = zr3 * zr - zi3 * zi + RePrim[j]; zi3 = zr3 * zi + zi3 * zr + ImPrim[j]; zr3 = Temp; } // f": zr4 = zi4 = 0; for (j = 0; j < c2; j++) { Temp = zr4 * zr - zi4 * zi + ReBis[j]; zi4 = zr4 * zi + zi4 * zr + ImBis[j]; zr4 = Temp; } // 2*f*f' zr5 = 2 * (zr2 * zr3 - zi2 * zi3); zi5 = 2 * (zr2 * zi3 + zi2 * zr3); // 2f'^2-f*f" zr6 = 2 * (zr3 * zr3 - zi3 * zi3) - (zr2 * zr4 - zi2 * zi4); zi6 = 4 * zr3 * zi3 - (zr2 * zi4 + zr4 * zi2); // R*2*f*f'/2f'^2-f*f" Temp = 1.0 / (zr6 * zr6 + zi6 * zi6); zr4 = (zr5 * zr6 + zi5 * zi6) * Temp; zi4 = (zi5 * zr6 - zr5 * zi6) * Temp; // R*2*f*f'/(2f'^2-f*f") Temp = zr4 * RRe - zi4 * RIm; zi4 = zr4 * RIm + zi4 * RRe; zr4 = Temp; zr -= zr4; zi -= zi4; Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4); }while ((Temp > Conv) && (Temp < Div) && (n++ < N)); if (Temp < Conv && n < N) { ColorIndex[index++] = n; } else { ColorIndex[index++] = N; } } } ColorIndex = FractalGraph.FindBoundaries(ColorIndex, Width, Height); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph CalcJulia(double rCenter, double iCenter, double R0, double I0, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State) { double r0, i0, r1, i1; double dr, di; double r, i; double zr, zi, zrt, zr2, zi2; double aspect; int x, y; int n, N; int index; N = Palette.Length; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; int Size = Width * Height; double[] ColorIndex = new double[Size]; for (y = 0, i = i0, index = 0; y < Height; y++, i += di) { for (x = 0, r = r0; x < Width; x++, r += dr) { zr = r; zi = i; n = 0; zr2 = zr * zr; zi2 = zi * zi; while (zr2 + zi2 < 9 && n < N) { n++; zrt = zr2 - zi2 + R0; zi = 2 * zr * zi + I0; zr = zrt; zr2 = zr * zr; zi2 = zi * zi; } if (n >= N) { ColorIndex[index++] = N; } else { ColorIndex[index++] = n; } } } Node.Expression.Preview(new GraphBitmap(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette))); double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height); FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }