2using System.Collections.Generic;
134 : base(new
ScriptNode[] { xc, yc, dr, N, Transforms, DimX, DimY, Seed },
146 : base(new
ScriptNode[] { xc, yc, dr, N, Transforms, DimX, DimY },
157 : base(new
ScriptNode[] { xc, yc, dr, N, Transforms, DimX },
168 : base(new
ScriptNode[] { xc, yc, dr, N, Transforms },
181 return new string[] {
"xc",
"yc",
"dr",
"N",
"Transforms",
"DimX",
"DimY",
"Seed" };
206 if (!(
Arguments[i].AssociatedObjectValue is Array Functions))
207 throw new ScriptRuntimeException(
"The fifth parameter to IfsFractal must be an array of homogenous 2D-transformations or lambda expressions.",
this);
209 List<DoubleMatrix> Matrices =
null;
210 List<ILambdaExpression> LambdaExpressions =
null;
211 List<double> Weights =
new List<double>();
212 List<SKColor> Colors =
new List<SKColor>();
213 string FunctionsExpression = this.Arguments[i++].SubExpression;
215 foreach (
object f
in Functions)
219 if (!(LambdaExpressions is
null))
222 if (Matrices is
null)
223 Matrices =
new List<DoubleMatrix>();
227 Colors.Add(SKColors.Black);
231 if (!(Matrices is
null))
234 if (LambdaExpressions is
null)
235 LambdaExpressions =
new List<ILambdaExpression>();
237 LambdaExpressions.Add(Lambda);
239 Colors.Add(SKColors.Black);
241 else if (f is SKColor || f is
string)
243 if (Colors.Count == 0)
244 throw new ScriptRuntimeException(
"Color definitions can only be specified after each transformation.",
this);
254 if (Weights.Count == 0)
255 throw new ScriptRuntimeException(
"Weight definitions can only be specified after each transformation.",
this);
257 Weights[Weights.Count - 1] = d;
261 throw new ScriptRuntimeException(
"The fifth parameter to IfsFractal must be an array of homogenous 2D-transformations or lambda expressions, optionally followed by their corresponding weights and/or colors.",
this);
290 throw new ScriptRuntimeException(
"Parameter mismatch in call to IfsFractal(xc,yc,dr,N,Transforms[,dimx[,dimy[,Seed]]]).",
294 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
297 if (!(Matrices is
null))
299 return CalcIfs(
Variables, xc, yc, dr, N, Matrices.ToArray(), Weights.ToArray(), Colors.ToArray(), dimx, dimy, Seed,
300 this,
this.FractalZoomScript,
new object[] { dimx, dimy, N, FunctionsExpression, Seed });
304 return CalcIfs(xc, yc, dr, N, LambdaExpressions.ToArray(), Weights.ToArray(), Colors.ToArray(),
305 dimx, dimy, Seed,
this,
Variables,
this.FractalZoomScript,
306 new object[] { dimx, dimy, N, FunctionsExpression, Seed });
310 private static readonly Random gen =
new Random();
317 private string FractalZoomScript(
double r,
double i,
double Size,
object State)
319 object[] Parameters = (
object[])State;
320 int DimX = (int)Parameters[0];
321 int DimY = (int)Parameters[1];
322 long N = (long)Parameters[2];
323 string FunctionsExpression = (string)Parameters[3];
324 int Seed = (int)Parameters[4];
326 StringBuilder sb =
new StringBuilder();
328 sb.Append(
"IfsFractal(");
335 sb.Append(N.ToString());
337 sb.Append(FunctionsExpression);
339 sb.Append(DimX.ToString());
341 sb.Append(DimY.ToString());
343 sb.Append(Seed.ToString());
346 return sb.ToString();
353 double[] Weights, SKColor[] Colors,
int Width,
int Height,
int Seed,
ScriptNode Node, FractalZoomScript FractalZoomScript,
object State)
357 double[][] Coefficients;
358 double TotWeight = 0;
364 int i, c = Functions.Length;
365 Random Gen =
new Random(Seed);
370 if (Weights.Length != c)
371 throw new ArgumentException(
"Weights must be of equal length as Functions.",
"Weights");
373 if (Colors.Length != c)
374 throw new ArgumentException(
"Colors must be of equal length as Functions.",
"Colors");
376 for (i = 0; i < c; i++)
382 Weights[i] += TotWeight;
389 for (i = 0; i < c; i++)
390 Weights[i] /= TotWeight;
392 Coefficients =
new double[c][];
394 Greens =
new byte[c];
397 for (i = 0; i < c; i++)
401 Greens[i] = cl.Green;
409 Coefficients[i] =
new double[]
411 (double)E[0, 0], (
double)E[0, 1], 0,
412 (double)E[1, 0], (
double)E[1, 1], 0,
418 Coefficients[i] =
new double[]
420 (double)E[0, 0], (
double)E[0, 1], (double)E[0, 2],
421 (
double)E[1, 0], (double)E[1, 1], (
double)E[1, 2],
422 (double)E[2, 0], (
double)E[2, 1], (double)E[2, 2]
426 throw new ScriptRuntimeException(
"Matrix not a linear 2D-transformation or a homogenous 2D-transformation.", Node);
429 int size = Width * Height * 4;
430 byte[] rgb =
new byte[size];
432 double AspectRatio = ((double)Width) / Height;
433 double x = Gen.NextDouble();
434 double y = Gen.NextDouble();
439 double xMin, xMax, yMin, yMax;
443 xMin = xCenter - rDelta / 2;
444 xMax = xMin + rDelta;
445 yMin = yCenter - rDelta / (2 * AspectRatio);
446 yMax = yMin + rDelta / AspectRatio;
448 sx = Width / (xMax - xMin);
449 sy = Height / (yMax - yMin);
451 for (i = 0; i < 20; i++)
453 Weight = Gen.NextDouble();
455 while (j < c - 1 && Weights[j] <= Weight)
460 x2 = C[0] * x + C[1] * y + C[2] * p;
461 y2 = C[3] * x + C[4] * y + C[5] * p;
462 p2 = C[6] * x + C[7] * y + C[8] * p;
471 Weight = Gen.NextDouble();
473 while (j < c - 1 && Weights[j] <= Weight)
478 x2 = C[0] * x + C[1] * y + C[2] * p;
479 y2 = C[3] * x + C[4] * y + C[5] * p;
480 p2 = C[6] * x + C[7] * y + C[8] * p;
489 if (x < xMin || x > xMax || y < yMin || y > yMax)
492 xi = (int)((x / p - xMin) * sx + 0.5);
493 yi = Height - 1 - (int)((y / p - yMin) * sy + 0.5);
495 if (xi < 0 || xi >= Width || yi < 0 || yi >= Height)
498 i = (yi * Width + xi) << 2;
503 rgb[i++] = Greens[j];
509 rgb[i] = (byte)((rgb[i] + Blues[j]) >> 1);
511 rgb[i] = (byte)((rgb[i] + Greens[j]) >> 1);
513 rgb[i] = (byte)((rgb[i] + Reds[j]) >> 1);
518 return new FractalGraph(
Variables, Pixels, xMin, yMin, xMax, yMax, rDelta,
false, Node,
FractalZoomScript, State);
525 ILambdaExpression[] Functions,
double[] Weights, SKColor[] Colors,
int Width,
int Height,
int Seed,
529 double TotWeight = 0;
536 int i, c = Functions.Length;
537 Random Gen =
new Random(Seed);
542 if (Weights.Length != c)
543 throw new ArgumentException(
"Weights must be of equal length as Functions.",
"Weights");
545 if (Colors.Length != c)
546 throw new ArgumentException(
"Colors must be of equal length as Functions.",
"Colors");
548 for (i = 0; i < c; i++)
554 Weights[i] += TotWeight;
561 for (i = 0; i < c; i++)
562 Weights[i] /= TotWeight;
566 Greens =
new byte[c];
569 for (i = 0; i < c; i++)
573 Greens[i] = cl.Green;
576 Lambda = Functions[i];
589 throw new ScriptRuntimeException(
"Lambda expressions in calls to IfsFractal() must be either real-values (taking two parameters) or complex valued (taking one parameter).", Node);
593 int size = Width * Height * 4;
594 byte[] rgb =
new byte[size];
596 double AspectRatio = ((double)Width) / Height;
597 double x = Gen.NextDouble();
598 double y = Gen.NextDouble();
600 double xMin, xMax, yMin, yMax;
612 xMin = xCenter - rDelta / 2;
613 xMax = xMin + rDelta;
614 yMin = yCenter - rDelta / (2 * AspectRatio);
615 yMax = yMin + rDelta / AspectRatio;
617 sx = Width / (xMax - xMin);
618 sy = Height / (yMax - yMin);
622 for (i = 0; i < 20; i++)
624 Weight = Gen.NextDouble();
626 while (j < c - 1 && Weights[j] <= Weight)
629 Lambda = Functions[j];
636 if (!(Lambda.
Evaluate(RealParameters, v) is
IVector Result) || Result.Dimension != 2)
644 zv.Value =
new Complex(x, y);
654 Weight = Gen.NextDouble();
656 while (j < c - 1 && Weights[j] <= Weight)
659 Lambda = Functions[j];
666 if (!(Lambda.
Evaluate(RealParameters, v) is
IVector Result) || Result.Dimension != 2)
674 zv.Value =
new Complex(x, y);
681 if (x < xMin || x > xMax || y < yMin || y > yMax)
684 xi = (int)((x - xMin) * sx + 0.5);
685 yi = Height - 1 - (int)((y - yMin) * sy + 0.5);
687 if (xi < 0 || xi >= Width || yi < 0 || yi >= Height)
690 i = (yi * Width + xi) << 2;
695 rgb[i++] = Greens[j];
701 rgb[i] = (byte)((rgb[i] + Blues[j]) >> 1);
703 rgb[i] = (byte)((rgb[i] + Greens[j]) >> 1);
705 rgb[i] = (byte)((rgb[i] + Reds[j]) >> 1);
710 return new FractalGraph(
Variables, Pixels, xMin, yMin, xMax, yMax, rDelta,
false, Node,
FractalZoomScript, State);
Script runtime exception.
Class managing a script expression.
static Complex ToComplex(object Object)
Converts an object to a complex value.
static double ToDouble(object Object)
Converts an object to a double value.
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
Defines a clickable fractal graph in the complex plane.
Calculates a fractal based on an Iterated Function System, using the chaos game.
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
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)
TODO
IfsFractal(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode Transforms, ScriptNode DimX, ScriptNode DimY, ScriptNode Seed, int Start, int Length, Expression Expression)
TODO
IfsFractal(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode Transforms, int Start, int Length, Expression Expression)
TODO
override string FunctionName
TODO
override string[] DefaultArgumentNames
TODO
static FractalGraph CalcIfs(Variables Variables, 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)
TODO
IfsFractal(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode Transforms, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
IfsFractal(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode Transforms, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
static SKColor ToColor(object Object)
Converts an object to a color.
Base class for multivariate funcions.
ScriptNode[] Arguments
Function arguments.
Base class for all nodes in a parsed script tree.
int Length
Length of expression covered by node.
Expression Expression
Expression of which the node is a part.
int Start
Start position in script expression.
double[,] Values
Matrix element values.
int Columns
Number of columns.
TextWriter ConsoleOut
Console out interface. Can be used by functions and script to output data to the console.
void CopyTo(Variables Variables)
Copies available variables to another variable collection.
Basic interface for all types of elements.
object AssociatedObjectValue
Associated object value.
Basic interface for vectors.
Base interface for lambda expressions.
IElement Evaluate(IElement[] Arguments, Variables Variables)
Evaluates the lambda expression.
int NrArguments
Number of arguments.
delegate string FractalZoomScript(double r, double i, double Size, object State)
Generates new script when zoomed.
ArgumentType
Type of parameter used in a function definition or a lambda definition.