public static FractalGraph CalcNewton(double rCenter, double iCenter, double rDelta, Complex R, Complex[] Coefficients, 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 zr, zi, zr2, zi2, zr3, zi3, zr4, zi4; double aspect; double Temp; int x, y; int n, N; int index; int Degree = Coefficients.Length - 1; 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; } if (Degree < 2) { Array.Resize <Complex>(ref Coefficients, 3); while (Degree < 2) { Coefficients[++Degree] = Complex.Zero; } } 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 * 4; double Conv = 1e-10; double Div = 1e10; byte[] rgb = new byte[size]; 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/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) { rgb[index++] = blues[n]; rgb[index++] = greens[n]; rgb[index++] = reds[n]; } else { rgb[index++] = 0; rgb[index++] = 0; rgb[index++] = 0; } rgb[index++] = 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 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)); } }
public static FractalGraph CalcHalley(double rCenter, double iCenter, double rDelta, Complex R, double[] Coefficients, 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 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; 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; } if (Degree < 3) { Array.Resize <double>(ref Coefficients, 4); while (Degree < 3) { Coefficients[++Degree] = 0; } } double[] Prim = new double[Degree]; for (x = 1; x <= Degree; x++) { Prim[x - 1] = x * Coefficients[x]; } double[] Bis = new double[Degree - 1]; for (x = 1; x < Degree; x++) { Bis[x - 1] = x * Prim[x]; } Array.Reverse(Bis); Array.Reverse(Prim); Coefficients = (double[])Coefficients.Clone(); Array.Reverse(Coefficients); int size = Width * Height * 4; double Conv = 1e-10; double Div = 1e10; byte[] rgb = new byte[size]; 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; foreach (double C in Coefficients) { Temp = zr2 * zr - zi2 * zi + C; zi2 = zr2 * zi + zi2 * zr; zr2 = Temp; } // f': zr3 = zi3 = 0; foreach (double C in Prim) { Temp = zr3 * zr - zi3 * zi + C; zi3 = zr3 * zi + zi3 * zr; zr3 = Temp; } // f": zr4 = zi4 = 0; foreach (double C in Bis) { Temp = zr4 * zr - zi4 * zi + C; zi4 = zr4 * zi + zi4 * zr; 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) { rgb[index++] = blues[n]; rgb[index++] = greens[n]; rgb[index++] = reds[n]; } else { rgb[index++] = 0; rgb[index++] = 0; rgb[index++] = 0; } rgb[index++] = 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 CalcFlame(double xCenter, double yCenter, double rDelta, long N, FlameFunction[] Functions, int Width, int Height, int Seed, int SuperSampling, double Gamma, double LightFactor, bool Preview, bool Parallel, Variables Variables, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { double TotWeight = 0; double Weight; int i, c = Functions.Length; Random Gen = new Random(Seed); if (c < 1) { throw new ScriptRuntimeException("At least one flame function needs to be provided.", Node); } if (SuperSampling < 1) { throw new ScriptRuntimeException("SuperSampling must be a postitive integer.", Node); } if (!Node.Expression.HandlesPreview) { Preview = false; } Array.Sort <FlameFunction>(Functions, (f1, f2) => { double d = f2.Weight - f1.Weight; if (d < 0) { return(-1); } else if (d > 0) { return(1); } else { return(0); } }); double[] SumWeights = new double[c]; FlameFunction f; for (i = 0; i < c; i++) { f = Functions[i]; Weight = f.Weight; if (Weight < 0) { throw new ScriptRuntimeException("Weights must be non-negative.", Node); } f.DefinitionDone(); TotWeight += Weight; SumWeights[i] = TotWeight; } if (TotWeight == 0) { throw new ScriptRuntimeException("The total weight of all functions must be postitive.", Node); } for (i = 0; i < c; i++) { SumWeights[i] /= TotWeight; } double AspectRatio = ((double)Width) / Height; double xMin, xMax, yMin, yMax; xMin = xCenter - rDelta / 2; xMax = xMin + rDelta; yMin = yCenter - rDelta / (2 * AspectRatio); yMax = yMin + rDelta / AspectRatio; int NrGames = Parallel ? System.Environment.ProcessorCount : 1; if (NrGames <= 1) { FlameState P = new FlameState(Gen, xMin, xMax, yMin, yMax, Width, Height, SuperSampling, N, ColorMode.Hsl, Node); Variables v = new Variables(); Variables.CopyTo(v); RunChaosGame(v, Functions, SumWeights, P, Preview, Gamma, LightFactor, Node, true); return(new FractalGraph(P.RenderBitmapHsl(Gamma, LightFactor, false, SKColors.Black), xMin, yMin, xMax, yMax, rDelta, false, Node, FractalZoomScript, State)); } else { FlameState[] P = new FlameState[NrGames]; WaitHandle[] Done = new WaitHandle[NrGames]; Thread[] T = new Thread[NrGames]; try { for (i = 0; i < NrGames; i++) { Done[i] = new ManualResetEvent(false); P[i] = new FlameState(Gen, xMin, xMax, yMin, yMax, Width, Height, SuperSampling, i < NrGames - 1 ? N / NrGames : N - (N / NrGames) * (NrGames - 1), ColorMode.Hsl, Node); Variables v = new Variables(); Variables.CopyTo(v); T[i] = new Thread(new ParameterizedThreadStart(ChaosGameThread)) { Name = "FlameFractal thread #" + (i + 1).ToString(), Priority = ThreadPriority.BelowNormal }; T[i].Start(new object[] { Done[i], i, v, Functions, SumWeights, P[i], Node, i == 0 ? Preview : false, Gamma, LightFactor }); } WaitHandle.WaitAll(Done); for (i = 1; i < NrGames; i++) { P[0].Add(P[i]); } return(new FractalGraph(P[0].RenderBitmapHsl(Gamma, LightFactor, false, SKColors.Black), xMin, yMin, xMax, yMax, rDelta, false, Node, FractalZoomScript, State)); } catch (ThreadAbortException) { for (i = 0; i < NrGames; i++) { try { if (T[i] == null) { continue; } if (Done[i] == null || !Done[i].WaitOne(0)) { T[i].Abort(); } } catch (Exception) { // Ignore } } return(null); } finally { for (i = 0; i < NrGames; i++) { try { if (Done[i] != null) { Done[i].Close(); } } catch (Exception) { // Ignore } } } } }
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 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 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)); } }
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 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 CalcNewton(double rCenter, double iCenter, double rDelta, Complex R, Complex[] Coefficients, 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, zr2, zi2, zr3, zi3, zr4, zi4; double aspect; double Temp; int x, y, b, c = 0, d; int n; int index; int Degree = Coefficients.Length - 1; if (Degree < 2) { Array.Resize <Complex>(ref Coefficients, 3); while (Degree < 2) { Coefficients[++Degree] = Complex.Zero; } } 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, e = Prim.Length; double[] ReC = new double[e + 1]; double[] ImC = new double[e + 1]; double[] RePrim = new double[e]; double[] ImPrim = new double[e]; Complex z; for (j = 0; j < e; 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 * 4; double Conv = 1e-10; double Div = 1e10; double Conv2 = Conv * 2; byte[] rgb = new byte[size]; 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 <= e; 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 < e; 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) { for (b = 0; b < c; b++) { if (Math.Abs(AttractorsR2[b] - zr) < Conv2 && Math.Abs(AttractorsI2[b] - zi) < Conv2) { break; } } if (b == c) { 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(); c++; } 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); } else { rgb[index++] = 0; rgb[index++] = 0; rgb[index++] = 0; } rgb[index++] = 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 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 CalcIfs(double xCenter, double yCenter, double rDelta, long N, ILambdaExpression[] Functions, double[] Weights, SKColor[] Colors, int Width, int Height, int Seed, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State) { ILambdaExpression Lambda; double TotWeight = 0; double Weight; bool[] Real; byte[] Reds; byte[] Greens; byte[] Blues; SKColor cl; int i, c = Functions.Length; Random Gen = new Random(Seed); if (c < 2) { throw new ScriptRuntimeException("At least two transformations need to be provided.", Node); } if (Weights.Length != c) { throw new ArgumentException("Weights must be of equal length as Functions.", "Weights"); } if (Colors.Length != c) { throw new ArgumentException("Colors must be of equal length as Functions.", "Colors"); } for (i = 0; i < c; i++) { Weight = Weights[i]; if (Weight < 0) { throw new ScriptRuntimeException("Weights must be non-negative.", Node); } Weights[i] += TotWeight; TotWeight += Weight; } if (TotWeight == 0) { throw new ScriptRuntimeException("The total weight of all functions must be postitive.", Node); } for (i = 0; i < c; i++) { Weights[i] /= TotWeight; } Real = new bool[c]; Reds = new byte[c]; Greens = new byte[c]; Blues = new byte[c]; for (i = 0; i < c; i++) { cl = Colors[i]; Reds[i] = cl.Red; Greens[i] = cl.Green; Blues[i] = cl.Blue; Lambda = Functions[i]; switch (Lambda.NrArguments) { case 1: Real[i] = false; break; case 2: Real[i] = true; break; default: throw new ScriptRuntimeException("Lambda expressions in calls to IfsFractal() must be either real-values (taking two parameters) or complex valued (taking one parameter).", Node); } } int size = Width * Height * 4; byte[] rgb = new byte[size]; double AspectRatio = ((double)Width) / Height; double x = Gen.NextDouble(); double y = Gen.NextDouble(); int j; double xMin, xMax, yMin, yMax; double sx, sy; DoubleNumber xv = new DoubleNumber(0); DoubleNumber yv = new DoubleNumber(0); ComplexNumber zv = new ComplexNumber(0); IElement[] RealParameters = new IElement[] { xv, yv }; IElement[] ComplexParameters = new IElement[] { zv }; Variables v = new Variables(); int xi, yi; Variables.CopyTo(v); xMin = xCenter - rDelta / 2; xMax = xMin + rDelta; yMin = yCenter - rDelta / (2 * AspectRatio); yMax = yMin + rDelta / AspectRatio; sx = Width / (xMax - xMin); sy = Height / (yMax - yMin); Complex z; for (i = 0; i < 20; i++) { Weight = Gen.NextDouble(); j = 0; while (j < c - 1 && Weights[j] <= Weight) { j++; } Lambda = Functions[j]; if (Real[j]) { xv.Value = x; yv.Value = y; if (!(Lambda.Evaluate(RealParameters, v) is IVector Result) || Result.Dimension != 2) { throw new ScriptRuntimeException("Expected 2-dimensional numeric vector as a result.", Node); } x = Expression.ToDouble(Result.GetElement(0).AssociatedObjectValue); y = Expression.ToDouble(Result.GetElement(1).AssociatedObjectValue); } else { zv.Value = new Complex(x, y); z = Expression.ToComplex(Lambda.Evaluate(ComplexParameters, v).AssociatedObjectValue); x = z.Real; y = z.Imaginary; } } while (N-- > 0) { Weight = Gen.NextDouble(); j = 0; while (j < c - 1 && Weights[j] <= Weight) { j++; } Lambda = Functions[j]; if (Real[j]) { xv.Value = x; yv.Value = y; if (!(Lambda.Evaluate(RealParameters, v) is IVector Result) || Result.Dimension != 2) { throw new ScriptRuntimeException("Expected 2-dimensional numeric vector as a result.", Node); } x = Expression.ToDouble(Result.GetElement(0).AssociatedObjectValue); y = Expression.ToDouble(Result.GetElement(1).AssociatedObjectValue); } else { zv.Value = new Complex(x, y); z = Expression.ToComplex(Lambda.Evaluate(ComplexParameters, v).AssociatedObjectValue); x = z.Real; y = z.Imaginary; } if (x < xMin || x > xMax || y < yMin || y > yMax) { continue; } xi = (int)((x - xMin) * sx + 0.5); yi = Height - 1 - (int)((y - yMin) * sy + 0.5); if (xi < 0 || xi >= Width || yi < 0 || yi >= Height) { continue; } i = (yi * Width + xi) << 2; if (rgb[i + 3] == 0) { rgb[i++] = Blues[j]; rgb[i++] = Greens[j]; rgb[i++] = Reds[j]; rgb[i] = 0xff; } else { rgb[i] = (byte)((rgb[i] + Blues[j]) >> 1); i++; rgb[i] = (byte)((rgb[i] + Greens[j]) >> 1); i++; rgb[i] = (byte)((rgb[i] + Reds[j]) >> 1); } } 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, xMin, yMin, xMax, yMax, rDelta, false, Node, FractalZoomScript, State)); } }
public static FractalGraph CalcIfs(double xCenter, double yCenter, double rDelta, long N, DoubleMatrix[] Functions, double[] Weights, SKColor[] Colors, int Width, int Height, int Seed, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { DoubleMatrix M; double[,] E; double[][] Coefficients; double TotWeight = 0; double Weight; SKColor cl; byte[] Reds; byte[] Greens; byte[] Blues; int i, c = Functions.Length; Random Gen = new Random(Seed); if (c < 2) { throw new ScriptRuntimeException("At least two transformations need to be provided.", Node); } if (Weights.Length != c) { throw new ArgumentException("Weights must be of equal length as Functions.", "Weights"); } if (Colors.Length != c) { throw new ArgumentException("Colors must be of equal length as Functions.", "Colors"); } for (i = 0; i < c; i++) { Weight = Weights[i]; if (Weight < 0) { throw new ScriptRuntimeException("Weights must be non-negative.", Node); } Weights[i] += TotWeight; TotWeight += Weight; } if (TotWeight == 0) { throw new ScriptRuntimeException("The total weight of all functions must be postitive.", Node); } for (i = 0; i < c; i++) { Weights[i] /= TotWeight; } Coefficients = new double[c][]; Reds = new byte[c]; Greens = new byte[c]; Blues = new byte[c]; for (i = 0; i < c; i++) { cl = Colors[i]; Reds[i] = cl.Red; Greens[i] = cl.Green; Blues[i] = cl.Blue; M = Functions[i]; E = M.Values; if (M.Columns == 2 && M.Rows == 2) { Coefficients[i] = new double[] { (double)E[0, 0], (double)E[0, 1], 0, (double)E[1, 0], (double)E[1, 1], 0, 0, 0, 1 }; } else if (M.Columns == 3 && M.Rows == 3) { Coefficients[i] = new double[] { (double)E[0, 0], (double)E[0, 1], (double)E[0, 2], (double)E[1, 0], (double)E[1, 1], (double)E[1, 2], (double)E[2, 0], (double)E[2, 1], (double)E[2, 2] }; } else { throw new ScriptRuntimeException("Matrix not a linear 2D-transformation or a homogenous 2D-transformation.", Node); } } int size = Width * Height * 4; byte[] rgb = new byte[size]; double AspectRatio = ((double)Width) / Height; double x = Gen.NextDouble(); double y = Gen.NextDouble(); double p = 1; double x2, y2, p2; double[] C; int j; double xMin, xMax, yMin, yMax; double sx, sy; int xi, yi; xMin = xCenter - rDelta / 2; xMax = xMin + rDelta; yMin = yCenter - rDelta / (2 * AspectRatio); yMax = yMin + rDelta / AspectRatio; sx = Width / (xMax - xMin); sy = Height / (yMax - yMin); for (i = 0; i < 20; i++) { Weight = Gen.NextDouble(); j = 0; while (j < c - 1 && Weights[j] <= Weight) { j++; } C = Coefficients[j]; x2 = C[0] * x + C[1] * y + C[2] * p; y2 = C[3] * x + C[4] * y + C[5] * p; p2 = C[6] * x + C[7] * y + C[8] * p; x = x2; y = y2; p = p2; } while (N-- > 0) { Weight = Gen.NextDouble(); j = 0; while (j < c - 1 && Weights[j] <= Weight) { j++; } C = Coefficients[j]; x2 = C[0] * x + C[1] * y + C[2] * p; y2 = C[3] * x + C[4] * y + C[5] * p; p2 = C[6] * x + C[7] * y + C[8] * p; x = x2; y = y2; p = p2; if (p == 0) { break; } if (x < xMin || x > xMax || y < yMin || y > yMax) { continue; } xi = (int)((x / p - xMin) * sx + 0.5); yi = Height - 1 - (int)((y / p - yMin) * sy + 0.5); if (xi < 0 || xi >= Width || yi < 0 || yi >= Height) { continue; } i = (yi * Width + xi) << 2; if (rgb[i + 3] == 0) { rgb[i++] = Blues[j]; rgb[i++] = Greens[j]; rgb[i++] = Reds[j]; rgb[i] = 0xff; } else { rgb[i] = (byte)((rgb[i] + Blues[j]) >> 1); i++; rgb[i] = (byte)((rgb[i] + Greens[j]) >> 1); i++; rgb[i] = (byte)((rgb[i] + Reds[j]) >> 1); } } 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, xMin, yMin, xMax, yMax, rDelta, false, Node, FractalZoomScript, State)); } }
public static FractalGraph CalcNovaMandelbrot(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) { byte[] reds; byte[] greens; byte[] blues; 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; SKColor cl; double lnz; double argz; double amp; double phi; 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; double Conv = 1e-10; double Div = 1e10; byte[] rgb = new byte[size]; 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: 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 + i; zr4 = Temp + r; zr -= zr4; zi -= zi4; Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4); }while ((Temp > Conv) && (Temp < Div) && (n++ < N)); if (Temp < Conv && n < N) { rgb[index++] = blues[n]; rgb[index++] = greens[n]; rgb[index++] = reds[n]; } else { rgb[index++] = 0; rgb[index++] = 0; rgb[index++] = 0; } rgb[index++] = 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 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)); }
public static FractalGraph CalcJulia(double rCenter, double iCenter, double R0, double I0, double rDelta, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { byte[] reds; byte[] greens; byte[] blues; 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; 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]; 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; 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) { rgb[index++] = 0; rgb[index++] = 0; rgb[index++] = 0; } else { rgb[index++] = blues[n]; rgb[index++] = greens[n]; rgb[index++] = reds[n]; } rgb[index++] = 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 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) { double r0, i0, r1, i1; double dr, di; double r, i; double aspect; int x, y; int n, N; 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]; int c, j, x2; Complex z; IElement[] P = new IElement[1]; IElement Obj; double Mod; 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, 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, Variables); 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 { ColorIndex[j++] = n; } } 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]; ColorIndex[j] = N; } } } Node.Expression.Preview(new GraphBitmap(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette))); double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height); FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph CalcNewtonSmooth(double rCenter, double iCenter, double rDelta, Complex R, Complex[] Coefficients, SKColor[] Palette, int Width, int Height, ScriptNode Node, Variables Variables, FractalZoomScript FractalZoomScript, object State) { double RRe = R.Real; double RIm = R.Imaginary; double r0, i0, r1, i1; double dr, di; double r, i; double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4; double aspect; double Temp; int x, y; int n, N; int Degree = Coefficients.Length - 1; N = Palette.Length; if (Degree < 2) { Array.Resize <Complex>(ref Coefficients, 3); while (Degree < 2) { Coefficients[++Degree] = Complex.Zero; } } if (Width <= 2 || Height <= 2) { throw new ScriptRuntimeException("Width and Height has to be greater than 2.", Node); } Complex[] Prim = new Complex[Degree]; for (x = 1; x <= Degree; x++) { Prim[x - 1] = x * Coefficients[x]; } Array.Reverse(Prim); Coefficients = (Complex[])Coefficients.Clone(); Array.Reverse(Coefficients); int j, c = Prim.Length; double[] ReC = new double[c + 1]; double[] ImC = new double[c + 1]; double[] RePrim = new double[c]; double[] ImPrim = new double[c]; Complex z; for (j = 0; j < c; j++) { z = Coefficients[j]; ReC[j] = z.Real; ImC[j] = z.Imaginary; z = Prim[j]; RePrim[j] = z.Real; ImPrim[j] = z.Imaginary; } z = Coefficients[j]; ReC[j] = z.Real; ImC[j] = z.Imaginary; int Size = Width * Height; double Conv = 1e-10; double Div = 1e10; double[] ColorIndex = new double[Size]; int Index = 0; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; for (y = 0, i = i0; y < Height; y++, i += di) { for (x = 0, r = r0; x < Width; x++, r += dr) { zr = r; zi = i; n = 0; do { // f: zr2 = zi2 = 0; for (j = 0; j <= c; j++) { Temp = zr2 * zr - zi2 * zi + ReC[j]; zi2 = zr2 * zi + zi2 * zr + ImC[j]; zr2 = Temp; } // f': zr3 = zi3 = 0; for (j = 0; j < c; j++) { Temp = zr3 * zr - zi3 * zi + RePrim[j]; zi3 = zr3 * zi + zi3 * zr + ImPrim[j]; zr3 = Temp; } // f/f': Temp = 1.0 / (zr3 * zr3 + zi3 * zi3); zr4 = (zr2 * zr3 + zi2 * zi3) * Temp; zi4 = (zi2 * zr3 - zr2 * zi3) * Temp; // R*f/f' Temp = zr4 * RRe - zi4 * RIm; zi4 = zr4 * RIm + zi4 * RRe; zr4 = Temp; zr -= zr4; zi -= zi4; Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4); }while ((Temp > Conv) && (Temp < Div) && (n++ < N)); if (Temp < Conv && n < N) { ColorIndex[Index++] = n; } else { ColorIndex[Index++] = N; } } } Node.Expression.Preview(new GraphBitmap(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette))); double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height); FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph CalcHalley(double rCenter, double iCenter, double rDelta, Complex R, Complex[] Coefficients, SKColor[] Palette, int Width, int Height, ScriptNode Node, FractalZoomScript FractalZoomScript, object State) { double RRe = R.Real; double RIm = R.Imaginary; double r0, i0, r1, i1; double dr, di; double r, i; double zr, zi, zr2, zi2, zr3, zi3, zr4, zi4, zr5, zi5, zr6, zi6; double aspect; double Temp; int x, y; int n, N; int index; int Degree = Coefficients.Length - 1; N = Palette.Length; if (Degree < 3) { Array.Resize <Complex>(ref Coefficients, 4); while (Degree < 3) { Coefficients[++Degree] = Complex.Zero; } } Complex[] Prim = new Complex[Degree]; for (x = 1; x <= Degree; x++) { Prim[x - 1] = x * Coefficients[x]; } Complex[] Bis = new Complex[Degree - 1]; for (x = 1; x < Degree; x++) { Bis[x - 1] = x * Prim[x]; } Array.Reverse(Bis); Array.Reverse(Prim); Coefficients = (Complex[])Coefficients.Clone(); Array.Reverse(Coefficients); int j, c = Prim.Length; int c2 = c - 1; double[] ReC = new double[c + 1]; double[] ImC = new double[c + 1]; double[] RePrim = new double[c]; double[] ImPrim = new double[c]; double[] ReBis = new double[c2]; double[] ImBis = new double[c2]; Complex z; for (j = 0; j < c; j++) { z = Coefficients[j]; ReC[j] = z.Real; ImC[j] = z.Imaginary; z = Prim[j]; RePrim[j] = z.Real; ImPrim[j] = z.Imaginary; if (j < c2) { z = Bis[j]; ReBis[j] = z.Real; ImBis[j] = z.Imaginary; } } z = Coefficients[j]; ReC[j] = z.Real; ImC[j] = z.Imaginary; int size = Width * Height; int[] ColorIndex = new int[size]; double Conv = 1e-10; double Div = 1e10; rDelta *= 0.5; r0 = rCenter - rDelta; r1 = rCenter + rDelta; aspect = ((double)Width) / Height; i0 = iCenter - rDelta / aspect; i1 = iCenter + rDelta / aspect; dr = (r1 - r0) / Width; di = (i1 - i0) / Height; for (y = 0, i = i0, index = 0; y < Height; y++, i += di) { for (x = 0, r = r0; x < Width; x++, r += dr) { zr = r; zi = i; n = 0; do { // f: zr2 = zi2 = 0; for (j = 0; j <= c; j++) { Temp = zr2 * zr - zi2 * zi + ReC[j]; zi2 = zr2 * zi + zi2 * zr + ImC[j]; zr2 = Temp; } // f': zr3 = zi3 = 0; for (j = 0; j < c; j++) { Temp = zr3 * zr - zi3 * zi + RePrim[j]; zi3 = zr3 * zi + zi3 * zr + ImPrim[j]; zr3 = Temp; } // f": zr4 = zi4 = 0; for (j = 0; j < c2; j++) { Temp = zr4 * zr - zi4 * zi + ReBis[j]; zi4 = zr4 * zi + zi4 * zr + ImBis[j]; zr4 = Temp; } // 2*f*f' zr5 = 2 * (zr2 * zr3 - zi2 * zi3); zi5 = 2 * (zr2 * zi3 + zi2 * zr3); // 2f'^2-f*f" zr6 = 2 * (zr3 * zr3 - zi3 * zi3) - (zr2 * zr4 - zi2 * zi4); zi6 = 4 * zr3 * zi3 - (zr2 * zi4 + zr4 * zi2); // R*2*f*f'/2f'^2-f*f" Temp = 1.0 / (zr6 * zr6 + zi6 * zi6); zr4 = (zr5 * zr6 + zi5 * zi6) * Temp; zi4 = (zi5 * zr6 - zr5 * zi6) * Temp; // R*2*f*f'/(2f'^2-f*f") Temp = zr4 * RRe - zi4 * RIm; zi4 = zr4 * RIm + zi4 * RRe; zr4 = Temp; zr -= zr4; zi -= zi4; Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4); }while ((Temp > Conv) && (Temp < Div) && (n++ < N)); if (Temp < Conv && n < N) { ColorIndex[index++] = n; } else { ColorIndex[index++] = N; } } } ColorIndex = FractalGraph.FindBoundaries(ColorIndex, Width, Height); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph CalcNovaJulia(double rCenter, double iCenter, double R0, double I0, double rDelta, double Rr, double Ri, double pr, double pi, 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, 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; int Size = Width * Height; double[] ColorIndex = new double[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: 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 + I0; zr4 = Temp + R0; zr -= zr4; zi -= zi4; Temp = Math.Sqrt(zr4 * zr4 + zi4 * zi4); }while ((Temp > Conv) && (Temp < Div) && (n++ < N)); if (Temp < Conv && n < N) { ColorIndex[index++] = n; } else { ColorIndex[index++] = N; } } } Node.Expression.Preview(new GraphBitmap(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette))); double[] Boundary = FractalGraph.FindBoundaries(ColorIndex, Width, Height); FractalGraph.Smooth(ColorIndex, Boundary, Width, Height, N, Palette, Node, Variables); return(new FractalGraph(FractalGraph.ToBitmap(ColorIndex, Width, Height, Palette), r0, i0, r1, i1, rDelta * 2, true, Node, FractalZoomScript, State)); }
public static FractalGraph 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); }