示例#1
0
        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));
        }
示例#2
0
        public static FractalGraph CalcJulia(double rCenter, double iCenter, ILambdaExpression f,
                                             ScriptNode fDef, double rDelta, SKColor[] Palette, int Width, int Height,
                                             ScriptNode Node, Variables Variables,
                                             FractalZoomScript FractalZoomScript, object State)
        {
            byte[]  reds;
            byte[]  greens;
            byte[]  blues;
            double  r0, i0, r1, i1;
            double  dr, di;
            double  r, i, Mod;
            double  aspect;
            int     x, x2, y;
            int     n, N;
            SKColor cl;

            N      = Palette.Length;
            reds   = new byte[N];
            greens = new byte[N];
            blues  = new byte[N];

            for (x = 0; x < N; x++)
            {
                cl        = Palette[x];
                reds[x]   = cl.Red;
                greens[x] = cl.Green;
                blues[x]  = cl.Blue;
            }

            int size = Width * Height * 4;

            byte[]  rgb = new byte[size];
            Complex z;

            IElement[] P = new IElement[1];
            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];
                int[]     Offset = new int[Width];

                c = Width;
                for (x = 0, x2 = y * Width * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
                {
                    Row[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);
                    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;
                                Offset[x2] = j;
                            }

                            x2++;
                        }
                        else
                        {
                            if (n >= N)
                            {
                                rgb[j++] = 0;
                                rgb[j++] = 0;
                                rgb[j++] = 0;
                            }
                            else
                            {
                                rgb[j++] = blues[n];
                                rgb[j++] = greens[n];
                                rgb[j++] = reds[n];
                            }

                            rgb[j++] = 255;
                        }
                    }

                    if (x2 < x)
                    {
                        Array.Resize <Complex>(ref Row, x2);
                        Array.Resize <int>(ref Offset, x2);
                        c = x2;
                    }
                }

                if (c > 0)
                {
                    for (x = 0; x < c; x++)
                    {
                        j = Offset[x];

                        rgb[j++] = 0;
                        rgb[j++] = 0;
                        rgb[j++] = 0;
                        rgb[j++] = 255;
                    }
                }
            }

            using (SKData Data = SKData.Create(new MemoryStream(rgb)))
            {
                SKImage Bitmap = SKImage.FromPixelData(new SKImageInfo(Width, Height, SKColorType.Bgra8888), Data, Width * 4);
                return(new FractalGraph(Bitmap, 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 CalcNewton(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)
        {
            byte[]  reds;
            byte[]  greens;
            byte[]  blues;
            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;
            SKColor cl;
            Complex z;

            N      = Palette.Length;
            reds   = new byte[N];
            greens = new byte[N];
            blues  = new byte[N];

            for (x = 0; x < N; x++)
            {
                cl        = Palette[x];
                reds[x]   = cl.Red;
                greens[x] = cl.Green;
                blues[x]  = cl.Blue;
            }

            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 * 4;
            double Conv = 1e-10;
            double Div  = 1e10;

            byte[] rgb = new byte[size];

            Complex[]  Row;
            Complex[]  Row2;
            Complex[]  Row3;
            int[]      Offset;
            IElement[] P = new IElement[1];
            int        j, c, x2;
            IElement   Obj, Obj2;
            double     Mod;

            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 * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
                {
                    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)
                            {
                                rgb[j++] = 0;
                                rgb[j++] = 0;
                                rgb[j++] = 0;
                            }
                            else
                            {
                                rgb[j++] = blues[n];
                                rgb[j++] = greens[n];
                                rgb[j++] = reds[n];
                            }

                            rgb[j++] = 255;
                        }
                    }

                    if (x2 < x)
                    {
                        Array.Resize <Complex>(ref Row, x2);
                        Array.Resize <int>(ref Offset, x2);
                        c = x2;
                    }
                }
            }

            using (SKData Data = SKData.Create(new MemoryStream(rgb)))
            {
                SKImage Bitmap = SKImage.FromPixelData(new SKImageInfo(Width, Height, SKColorType.Bgra8888), Data, Width * 4);
                return(new FractalGraph(Bitmap, r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State));
            }
        }
示例#5
0
        public static FractalGraph CalcNewton(double rCenter, double iCenter, double rDelta, Complex R,
                                              ILambdaExpression f, ScriptNode fDef, Variables Variables, int N, int Width, int Height,
                                              ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
        {
            double        RRe             = R.Real;
            double        RIm             = R.Imaginary;
            List <double> AttractorsR     = new List <double>();
            List <double> AttractorsI     = new List <double>();
            List <int>    AttractorColors = new List <int>();

            double[] AttractorsR2 = new double[0];
            double[] AttractorsI2 = new double[0];
            int[]    AttractorsColors2 = new int[0];
            double   r0, i0, r1, i1;
            double   dr, di;
            double   r, i;
            double   zr, zi;
            double   aspect;
            int      x, y, b, c, d;
            int      NrAttractors = 0;
            int      n;
            int      index;

            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 * 4;
            double Conv  = 1e-10;
            double Div   = 1e10;
            double Conv2 = Conv * 2;

            byte[] rgb = new byte[size];

            Complex[]  Row;
            Complex[]  Row2;
            Complex[]  Row3;
            int[]      Offset;
            IElement[] P = new IElement[1];
            int        j, 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, index = 0; y < Height; y++, i += di)
            {
                Row    = new Complex[Width];
                Offset = new int[Width];

                c = Width;
                for (x = 0, x2 = y * Width * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
                {
                    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)
                            {
                                rgb[j++] = 0;
                                rgb[j++] = 0;
                                rgb[j++] = 0;
                            }
                            else
                            {
                                zr = z.Real;
                                zi = z.Imaginary;

                                for (b = 0; b < NrAttractors; b++)
                                {
                                    if (Math.Abs(AttractorsR2[b] - zr) < Conv2 &&
                                        Math.Abs(AttractorsI2[b] - zi) < Conv2)
                                    {
                                        break;
                                    }
                                }

                                if (b == NrAttractors)
                                {
                                    AttractorsR.Add(zr);
                                    AttractorsI.Add(zi);

                                    int p1 = ~((b % 6) + 1);
                                    int p2 = ((b / 6) % 7);

                                    int Red   = (p1 & 1) != 0 ? 255 : 0;
                                    int Green = (p1 & 2) != 0 ? 255 : 0;
                                    int Blue  = (p1 & 4) != 0 ? 255 : 0;

                                    if ((p2 & 1) != 0)
                                    {
                                        Red >>= 1;
                                    }

                                    if ((p2 & 2) != 0)
                                    {
                                        Green >>= 1;
                                    }

                                    if ((p2 & 4) != 0)
                                    {
                                        Blue >>= 1;
                                    }

                                    Blue <<= 8;
                                    Blue  |= Green;
                                    Blue <<= 8;
                                    Blue  |= Red;

                                    AttractorColors.Add(Blue);

                                    AttractorsR2      = AttractorsR.ToArray();
                                    AttractorsI2      = AttractorsI.ToArray();
                                    AttractorsColors2 = AttractorColors.ToArray();

                                    NrAttractors++;
                                }

                                b = AttractorColors[b];

                                d            = (byte)b;
                                rgb[index++] = (byte)((d * (N - n + 1)) / N);
                                b          >>= 8;
                                d            = (byte)b;
                                rgb[index++] = (byte)((d * (N - n + 1)) / N);
                                b          >>= 8;
                                d            = (byte)b;
                                rgb[index++] = (byte)((d * (N - n + 1)) / N);
                            }

                            rgb[j++] = 255;
                        }
                    }

                    if (x2 < x)
                    {
                        Array.Resize <Complex>(ref Row, x2);
                        Array.Resize <int>(ref Offset, x2);
                        c = x2;
                    }
                }
            }

            using (SKData Data = SKData.Create(new MemoryStream(rgb)))
            {
                SKImage Bitmap = SKImage.FromPixelData(new SKImageInfo(Width, Height, SKColorType.Bgra8888), Data, Width * 4);
                return(new FractalGraph(Bitmap, r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State));
            }
        }
示例#6
0
        public static FractalGraph CalcHalley(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)
        {
            byte[]  reds;
            byte[]  greens;
            byte[]  blues;
            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;
            SKColor cl;

            N      = Palette.Length;
            reds   = new byte[N];
            greens = new byte[N];
            blues  = new byte[N];

            for (x = 0; x < N; x++)
            {
                cl        = Palette[x];
                reds[x]   = cl.Red;
                greens[x] = cl.Green;
                blues[x]  = cl.Blue;
            }

            Variables v = new Variables();

            Variables.CopyTo(v);

            string ParameterName;

            if (!(f is IDifferentiable Differentiable) ||
                !(Differentiable.Differentiate(ParameterName = Differentiable.DefaultVariableName, v) is ILambdaExpression fPrim))
            {
                throw new ScriptRuntimeException("Lambda expression not differentiable.", Node);
            }

            if (!(fPrim is IDifferentiable Differentiable2) ||
                !(Differentiable2.Differentiate(ParameterName, v) is ILambdaExpression fBis))
            {
                throw new ScriptRuntimeException("Lambda expression not twice differentiable.", Node);
            }

            int    size = Width * Height * 4;
            double Conv = 1e-10;
            double Div  = 1e10;

            byte[] rgb = new byte[size];

            Complex[]  Row;
            Complex[]  Row2;
            Complex[]  Row3;
            Complex[]  Row4;
            int[]      Offset;
            IElement[] P = new IElement[1];
            int        j, c, x2;
            IElement   Obj, Obj2, Obj3;
            double     Mod;
            Complex    z, z2, z3;
            Complex    R2 = R * 2;

            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 * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
                {
                    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);
                    Obj3 = fBis.Evaluate(P, v);
                    Row2 = Obj.AssociatedObjectValue as Complex[];
                    Row3 = Obj2.AssociatedObjectValue as Complex[];
                    Row4 = Obj3.AssociatedObjectValue as Complex[];

                    if (Row2 is null || Row3 is null || Row4 is null)
                    {
                        throw new ScriptRuntimeException("Lambda expression (and its first and second derivative) must be able to accept complex vectors, " +
                                                         "and return complex vectors of equal length. Type returned: " +
                                                         Obj.GetType().FullName + ", " + Obj2.GetType().FullName + " and " + Obj3.GetType().FullName,
                                                         Node);
                    }
        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 is null || Row3 is 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);
                    }
        public static FractalGraph CalcNewton(double rCenter, double iCenter, double rDelta, Complex R,
                                              ILambdaExpression f, ScriptNode fDef, Variables Variables, int N, int Width, int Height,
                                              ScriptNode Node, FractalZoomScript FractalZoomScript, object State)
        {
            double        RRe             = R.Real;
            double        RIm             = R.Imaginary;
            List <double> AttractorsR     = new List <double>();
            List <double> AttractorsI     = new List <double>();
            List <int>    AttractorColors = new List <int>();

            double[] AttractorsR2 = new double[0];
            double[] AttractorsI2 = new double[0];
            int[]    AttractorsColors2 = new int[0];
            double   r0, i0, r1, i1;
            double   dr, di;
            double   r, i;
            double   zr, zi;
            double   aspect;
            int      x, y, b, c, d;
            int      NrAttractors = 0;
            int      n;
            int      index;

            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 * 4;
            double Conv  = 1e-10;
            double Div   = 1e10;
            double Conv2 = Conv * 2;

            byte[] rgb = new byte[size];

            Complex[]  Row;
            Complex[]  Row2;
            Complex[]  Row3;
            int[]      Offset;
            IElement[] P = new IElement[1];
            int        j, 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, index = 0; y < Height; y++, i += di)
            {
                Row    = new Complex[Width];
                Offset = new int[Width];

                c = Width;
                for (x = 0, x2 = y * Width * 4, r = r0; x < Width; x++, r += dr, x2 += 4)
                {
                    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 is null || Row3 is 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);
                    }