コード例 #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 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));
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        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));
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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));
        }