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 override IElement Evaluate(IElement[] Arguments, Variables Variables)
        {
            string ColorExpression = null;

            SKColor[] Palette;
            object    Obj;
            double    rc, ic;
            double    dr;
            double    Rr, Ri, pr, pi;
            int       dimx, dimy;
            int       i, c;

            rc = Expression.ToDouble(Arguments[0].AssociatedObjectValue);
            ic = Expression.ToDouble(Arguments[1].AssociatedObjectValue);
            dr = Expression.ToDouble(Arguments[2].AssociatedObjectValue);

            if ((Obj = Arguments[3].AssociatedObjectValue) is Complex)
            {
                Complex z = (Complex)Obj;
                Rr = z.Real;
                Ri = z.Imaginary;
            }
            else
            {
                Rr = Expression.ToDouble(Arguments[3].AssociatedObjectValue);
                Ri = 0;
            }

            if ((Obj = Arguments[4].AssociatedObjectValue) is Complex)
            {
                Complex z = (Complex)Obj;
                pr = z.Real;
                pi = z.Imaginary;
            }
            else
            {
                pr = Expression.ToDouble(Arguments[4].AssociatedObjectValue);
                pi = 0;
            }

            c = Arguments.Length;
            i = 5;

            if (i < c && this.Arguments[i] != null && Arguments[i] is ObjectVector)
            {
                ColorExpression = this.Arguments[i].SubExpression;
                Palette         = FractalGraph.ToPalette((ObjectVector)Arguments[i++]);
            }
            else
            {
                Palette         = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out int Seed, this, Variables);
                ColorExpression = "RandomLinearAnalogousHSL(128,4," + Seed.ToString() + ")";

                if (i < c && this.Arguments[i] is null)
                {
                    i++;
                }
            }

            if (i < c)
            {
                dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                dimx = 320;
            }

            if (i < c)
            {
                dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                dimy = 200;
            }

            if (i < c)
            {
                throw new ScriptRuntimeException("Parameter mismatch in call to NovaTopographyFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
                                                 this);
            }

            if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
            {
                throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
            }

            return(CalcNova(rc, ic, dr, Rr, Ri, pr, pi, Palette, dimx, dimy,
                            this, this.FractalZoomScript,
                            new object[] { Palette, dimx, dimy, Rr, Ri, pr, pi, ColorExpression }));
        }
示例#3
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));
        }
示例#4
0
        public override IElement Evaluate(IElement[] Arguments, Variables Variables)
        {
            string ColorExpression = null;

            SKColor[]         Palette;
            double            rc, ic;
            double            dr;
            int               dimx, dimy;
            int               i, c;
            object            Obj;
            Complex           z;
            ILambdaExpression f;
            ScriptNode        fDef = null;

            c = Arguments.Length;
            i = 0;

            Obj = Arguments[i++].AssociatedObjectValue;
            if (Obj is Complex)
            {
                z  = (Complex)Obj;
                rc = z.Real;
                ic = z.Imaginary;
            }
            else
            {
                rc = Expression.ToDouble(Obj);
                ic = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }

            if (i >= c)
            {
                throw new ScriptRuntimeException("Insufficient parameters in call to MandelbrotTopographyFractal().", this);
            }

            Obj = Arguments[i].AssociatedObjectValue;
            if (Obj is ILambdaExpression)
            {
                f    = (ILambdaExpression)Obj;
                fDef = this.Arguments[i++];

                if (f.NrArguments != 2)
                {
                    throw new ScriptRuntimeException("Lambda expression in calls to MandelbrotTopographyFractal() must be of two variables (z,c).", this);
                }
            }
            else
            {
                f    = null;
                fDef = null;

                if (Obj == null)
                {
                    i++;
                }
            }

            dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);

            if (i < c && this.Arguments[i] != null && Arguments[i] is ObjectVector)
            {
                ColorExpression = this.Arguments[i].SubExpression;
                Palette         = FractalGraph.ToPalette((ObjectVector)Arguments[i++]);
            }
            else
            {
                Palette         = ColorModels.RandomLinearAnalogousHSL.CreatePalette(1024, 16, out int Seed, this, Variables);
                ColorExpression = "RandomLinearAnalogousHSL(1024,16," + Seed.ToString() + ")";

                if (i < c && this.Arguments[i] == null)
                {
                    i++;
                }
            }

            if (i < c)
            {
                dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                dimx = 320;
            }

            if (i < c)
            {
                dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                dimy = 200;
            }

            if (i < c)
            {
                throw new ScriptRuntimeException("Parameter mismatch in call to MandelbrotTopographyFractal(r,c,dr[,Palette][,dimx[,dimy]]).",
                                                 this);
            }

            if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
            {
                throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
            }

            if (f != null)
            {
                return(CalcMandelbrot(rc, ic, dr, f, Variables, Palette, dimx, dimy, this, this.FractalZoomScript,
                                      new object[] { Palette, dimx, dimy, ColorExpression, fDef }));
            }
            else
            {
                return(CalcMandelbrot(rc, ic, dr, Palette, dimx, dimy, this, this.FractalZoomScript,
                                      new object[] { Palette, dimx, dimy, ColorExpression, fDef }));
            }
        }
        public override IElement Evaluate(IElement[] Arguments, Variables Variables)
        {
            string ColorExpression = null;

            SKColor[]         Palette;
            double[]          Coefficients = null;
            Complex[]         CoefficientsZ = null;
            ILambdaExpression f = null;
            ScriptNode        fDef = null;
            double            rc, ic;
            double            dr;
            Complex           R;
            int     dimx, dimy;
            int     c = Arguments.Length;
            int     i = 0;
            object  Obj;
            Complex z;

            Obj = Arguments[i++].AssociatedObjectValue;
            if (Obj is Complex)
            {
                z  = (Complex)Obj;
                rc = z.Real;
                ic = z.Imaginary;
            }
            else
            {
                rc = Expression.ToDouble(Obj);
                ic = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }

            if (i >= c)
            {
                throw new ScriptRuntimeException("Insufficient parameters in call to NewtonSmoothFractal().", this);
            }

            dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);

            if (i < c && (Arguments[i] is DoubleNumber || Arguments[i] is ComplexNumber))
            {
                R = Expression.ToComplex(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                R = Complex.One;

                if (i < c && this.Arguments[i] == null)
                {
                    i++;
                }
            }

            if (i < c)
            {
                if (Arguments[i] is DoubleVector)
                {
                    Coefficients = (double[])Arguments[i++].AssociatedObjectValue;
                }
                else if (Arguments[i] is ComplexVector)
                {
                    CoefficientsZ = (Complex[])Arguments[i++].AssociatedObjectValue;
                }

                /*else if (Parameters[i] is RealPolynomial)
                 *      Coefficients = ((RealPolynomial)Arguments[i++].AssociatedObjectValue).Coefficients;
                 * else if (Parameters[i] is ComplexPolynomial)
                 *      CoefficientsZ = ((ComplexPolynomial)Arguments[i++].AssociatedObjectValue).Coefficients;*/
                else if (Arguments[i] is IVector)
                {
                    IVector Vector = (IVector)Arguments[i++];
                    int     j, d = Vector.Dimension;

                    CoefficientsZ = new Complex[d];
                    for (j = 0; j < d; j++)
                    {
                        CoefficientsZ[j] = Expression.ToComplex(Vector.GetElement(j).AssociatedObjectValue);
                    }
                }
                else if (Arguments[i].AssociatedObjectValue is ILambdaExpression)
                {
                    f = (ILambdaExpression)Arguments[i];
                    if (f.NrArguments != 1)
                    {
                        throw new ScriptRuntimeException("Lambda expression in calls to NewtonSmoothFractal() must be of one variable.", this);
                    }

                    fDef = this.Arguments[i++];
                }
                else
                {
                    throw new ScriptRuntimeException("Parameter " + (i + 1).ToString() +
                                                     " in call to NewtonSmoothFractal has to be a vector of numbers, containing coefficients " +
                                                     "of the polynomial to use. Now it was of type " + Arguments[i].GetType().FullName,
                                                     this);
                }
            }
            else
            {
                throw new ScriptRuntimeException("Missing coefficients or lambda expression.", this);
            }

            if (i < c && this.Arguments[i] != null && Arguments[i] is ObjectVector)
            {
                ColorExpression = this.Arguments[i].SubExpression;
                Palette         = FractalGraph.ToPalette((ObjectVector)Arguments[i++]);
            }
            else
            {
                Palette         = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out int Seed, this, Variables);
                ColorExpression = "RandomLinearAnalogousHSL(128,4," + Seed.ToString() + ")";

                if (i < c && this.Arguments[i] == null)
                {
                    i++;
                }
            }

            if (i < c)
            {
                dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                dimx = 320;
            }

            if (i < c)
            {
                dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                dimy = 200;
            }

            if (i < c)
            {
                throw new ScriptRuntimeException("Parameter mismatch in call to NewtonSmoothFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
                                                 this);
            }

            if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
            {
                throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
            }

            if (f != null)
            {
                return(CalcNewtonSmooth(rc, ic, dr, R, f, fDef, Variables, Palette, dimx, dimy,
                                        this, this.FractalZoomScript,
                                        new object[] { Palette, dimx, dimy, R, fDef, ColorExpression }));
            }
            else if (CoefficientsZ != null)
            {
                return(CalcNewtonSmooth(rc, ic, dr, R, CoefficientsZ, Palette, dimx, dimy,
                                        this, Variables, this.FractalZoomScript,
                                        new object[] { Palette, dimx, dimy, R, CoefficientsZ, ColorExpression }));
            }
            else
            {
                return(CalcNewtonSmooth(rc, ic, dr, R, Coefficients, Palette, dimx, dimy,
                                        this, Variables, this.FractalZoomScript,
                                        new object[] { Palette, dimx, dimy, R, Coefficients, ColorExpression }));
            }
        }
示例#6
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));
        }
        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));
        }
示例#9
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));
        }
示例#10
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));
        }
示例#11
0
        public override IElement Evaluate(IElement[] Arguments, Variables Variables)
        {
            string ColorExpression = null;

            SKColor[] Palette;
            double[]  Coefficients = null;
            Complex[] CoefficientsZ = null;
            double    rc, ic;
            double    dr;
            Complex   R;
            int       dimx, dimy;
            int       c = Arguments.Length;
            int       i = 0;
            object    Obj;
            Complex   z;

            Obj = Arguments[i++].AssociatedObjectValue;
            if (Obj is Complex)
            {
                z  = (Complex)Obj;
                rc = z.Real;
                ic = z.Imaginary;
            }
            else
            {
                rc = Expression.ToDouble(Obj);
                ic = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }

            if (i >= c)
            {
                throw new ScriptRuntimeException("Insufficient parameters in call to NewtonBuilderFractal().", this);
            }

            dr = Expression.ToDouble(Arguments[i++].AssociatedObjectValue);

            if (i < c && (Arguments[i] is DoubleNumber || Arguments[i] is ComplexNumber))
            {
                R = Expression.ToComplex(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                R = Complex.One;

                if (i < c && this.Arguments[i] == null)
                {
                    i++;
                }
            }

            if (i < c && Arguments[i] is DoubleVector)
            {
                Coefficients = (double[])Arguments[i++].AssociatedObjectValue;

                int j, d = Coefficients.Length;

                CoefficientsZ = new Complex[d];
                for (j = 0; j < d; j++)
                {
                    CoefficientsZ[j] = new Complex(Coefficients[j], 0);
                }
            }
            else if (i < c && Arguments[i] is ComplexVector)
            {
                CoefficientsZ = (Complex[])Arguments[i++].AssociatedObjectValue;
            }

            /*else if (i < c && Parameters[i] is RealPolynomial)
             *  Coefficients = ((RealPolynomial)Arguments[i++].AssociatedObjectValue).Coefficients;
             * else if (i < c && Parameters[i] is ComplexPolynomial)
             *  CoefficientsZ = ((ComplexPolynomial)Arguments[i++].AssociatedObjectValue).Coefficients;*/
            else if (i < c && Arguments[i] is IVector)
            {
                IVector Vector = (IVector)Arguments[i++];
                int     j, d = Vector.Dimension;

                CoefficientsZ = new Complex[d];
                for (j = 0; j < d; j++)
                {
                    CoefficientsZ[j] = Expression.ToComplex(Vector.GetElement(j).AssociatedObjectValue);
                }
            }
            else
            {
                CoefficientsZ = new Complex[0];
            }

            if (i < c && this.Arguments[i] != null && Arguments[i] is ObjectVector)
            {
                ColorExpression = this.Arguments[i].SubExpression;
                Palette         = FractalGraph.ToPalette((ObjectVector)Arguments[i++]);
            }
            else
            {
                Palette         = ColorModels.RandomLinearAnalogousHSL.CreatePalette(128, 4, out int Seed, this, Variables);
                ColorExpression = "RandomLinearAnalogousHSL(128,4," + Seed.ToString() + ")";

                if (i < c && this.Arguments[i] == null)
                {
                    i++;
                }
            }

            if (i < c)
            {
                dimx = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                dimx = 320;
            }

            if (i < c)
            {
                dimy = (int)Expression.ToDouble(Arguments[i++].AssociatedObjectValue);
            }
            else
            {
                dimy = 200;
            }

            if (i < c)
            {
                throw new ScriptRuntimeException("Parameter mismatch in call to NewtonBuilderFractal(r,c,dr,Coefficients[,Palette][,dimx[,dimy]]).",
                                                 this);
            }

            if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
            {
                throw new ScriptRuntimeException("Image size must be within 1x1 to 5000x5000", this);
            }

            return(NewtonFractal.CalcNewton(rc, ic, dr, R, CoefficientsZ, Palette, dimx, dimy,
                                            this, this.FractalZoomScript,
                                            new object[] { Palette, dimx, dimy, R, CoefficientsZ, ColorExpression, rc, ic }));
        }