3using System.Collections.Generic;
28 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions, Preview, Parallel, DimX, DimY, SuperSampling,
29 Gamma, LightFactor, Seed },
43 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions, Preview, Parallel, DimX, DimY, SuperSampling,
58 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions, Preview, Parallel, DimX, DimY, SuperSampling,
73 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions, Preview, Parallel, DimX, DimY, SuperSampling },
87 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions, Preview, Parallel, DimX, DimY },
100 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions, Preview, Parallel, DimX },
103 ArgumentType.Scalar },
113 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions, Preview, Parallel },
125 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions, Preview },
137 : base(new
ScriptNode[] { xc, yc, dr, N, FlameFunctions },
153 "xc",
"yc",
"dr",
"N",
"FlameFunctions",
"Preview",
"Parallel",
154 "DimX",
"DimY",
"SuperSampling",
"Gamma",
"LightFactor",
"Seed"
185 object Obj =
Arguments[i].AssociatedObjectValue;
186 string FunctionsExpression = this.Arguments[i++].SubExpression;
188 if (!(Obj is Array FlameArray))
189 throw new ScriptRuntimeException(
"The fifth parameter to FlameFractalHsl must be an array, containing flame definitions.",
this);
191 List<FlameFunction> FlameFunctions =
new List<FlameFunction>();
198 foreach (
object FlameItem
in FlameArray)
203 FlameFunctions.Add(CurrentFunction);
205 else if (FlameItem is SKColor || FlameItem is
string)
207 if (CurrentFunction is
null)
209 M =
new DoubleMatrix(
new double[,] { { 1, 0 }, { 0, 1 } });
211 FlameFunctions.Add(CurrentFunction);
215 cl.ToHsl(out
float H, out
float S, out
float L);
217 CurrentFunction.SetColorHsl(H, S, L);
218 CurrentFunction =
null;
222 if (CurrentFunction is
null)
224 M =
new DoubleMatrix(
new double[,] { { 1, 0 }, { 0, 1 } });
226 FlameFunctions.Add(CurrentFunction);
229 CurrentFunction.Add(FlameVariation);
233 if (CurrentFunction is
null)
235 M =
new DoubleMatrix(
new double[,] { { 1, 0 }, { 0, 1 } });
237 FlameFunctions.Add(CurrentFunction);
240 CurrentFunction.Add(LambdaExpression);
248 if (CurrentFunction is
null)
250 M =
new DoubleMatrix(
new double[,] { { 1, 0 }, { 0, 1 } });
252 FlameFunctions.Add(CurrentFunction);
255 CurrentFunction.SetWeight(Weight);
264 if (i < c &&
Arguments[i].AssociatedObjectValue is
bool Preview)
269 if (i < c &&
Arguments[i].AssociatedObjectValue is
bool Parallel)
313 throw new ScriptRuntimeException(
"Parameter mismatch in call to FlameFractalHsl(xc,yc,dr,N,FlameFunctions[,Preview[,Parallel[,dimx[,dimy[,SuperSampling[,Gamma[,LightFactor[,Seed]]]]]]]]).",
317 if (dimx <= 0 || dimx > 5000 || dimy <= 0 || dimy > 5000)
331 return CalcFlame(xc, yc, dr, N, Functions, dimx, dimy, Seed, SuperSampling, Gamma, LightFactor, Preview, Parallel,
Variables,
this,
332 this.FractalZoomScript,
new object[] { dimx, dimy, N, FunctionsExpression, Seed, SuperSampling, Gamma, LightFactor, Preview, Parallel });
335 private readonly
static Random gen =
new Random();
337 private string FractalZoomScript(
double r,
double i,
double Size,
object State)
339 object[] Parameters = (
object[])State;
340 int DimX = (int)Parameters[0];
341 int DimY = (int)Parameters[1];
342 long N = (long)Parameters[2];
343 string FunctionsExpression = (string)Parameters[3];
344 int Seed = (int)Parameters[4];
345 int SuperSampling = (int)Parameters[5];
346 double Gamma = (double)Parameters[6];
347 double LightFactor = (double)Parameters[7];
348 bool Preview = (bool)Parameters[8];
349 bool Parallel = (bool)Parameters[9];
351 StringBuilder sb =
new StringBuilder();
353 sb.Append(
"FlameFractalHsl(");
360 sb.Append(N.ToString());
362 sb.Append(FunctionsExpression);
368 sb.Append(DimX.ToString());
370 sb.Append(DimY.ToString());
372 sb.Append(SuperSampling.ToString());
378 sb.Append(Seed.ToString());
381 return sb.ToString();
388 FlameFunction[] Functions,
int Width,
int Height,
int Seed,
int SuperSampling,
double Gamma,
390 FractalZoomScript FractalZoomScript,
object State)
392 double TotWeight = 0;
394 int i, c = Functions.Length;
395 Random Gen =
new Random(Seed);
400 if (SuperSampling < 1)
406 Array.Sort(Functions, (f1, f2) =>
408 double d = f2.Weight - f1.
Weight;
417 double[] SumWeights =
new double[c];
420 for (i = 0; i < c; i++)
429 SumWeights[i] = TotWeight;
435 for (i = 0; i < c; i++)
436 SumWeights[i] /= TotWeight;
438 double AspectRatio = ((double)Width) / Height;
439 double xMin, xMax, yMin, yMax;
441 xMin = xCenter - rDelta / 2;
442 xMax = xMin + rDelta;
443 yMin = yCenter - rDelta / (2 * AspectRatio);
444 yMax = yMin + rDelta / AspectRatio;
446 int NrGames = Parallel ? System.Environment.ProcessorCount : 1;
450 FlameState P =
new FlameState(Gen, xMin, xMax, yMin, yMax, Width, Height, SuperSampling, N, ColorMode.Hsl, Node);
454 RunChaosGame(v, Functions, SumWeights, P, Preview, Gamma, LightFactor, Node);
456 return new FractalGraph(
Variables, P.RenderBitmapHsl(Gamma, LightFactor,
false, SKColors.Black), xMin, yMin, xMax, yMax, rDelta,
461 FlameState[] P =
new FlameState[NrGames];
462 WaitHandle[] Done =
new WaitHandle[NrGames];
463 Thread[] T =
new Thread[NrGames];
467 for (i = 0; i < NrGames; i++)
469 Done[i] =
new ManualResetEvent(
false);
470 P[i] =
new FlameState(Gen, xMin, xMax, yMin, yMax, Width, Height, SuperSampling,
471 i < NrGames - 1 ? N / NrGames : N - (N / NrGames) * (NrGames - 1),
472 ColorMode.Hsl, Node);
477 T[i] =
new Thread(
new ParameterizedThreadStart(ChaosGameThread))
479 Name =
"FlameFractal thread #" + (i + 1).
ToString(),
480 Priority = ThreadPriority.BelowNormal
483 T[i].Start(
new object[] { Done[i], i, v, Functions, SumWeights, P[i],
484 Node, i == 0 && Preview, Gamma, LightFactor });
487 WaitHandle.WaitAll(Done);
489 for (i = 1; i < NrGames; i++)
492 return new FractalGraph(
Variables, P[0].RenderBitmapHsl(Gamma, LightFactor,
false, SKColors.Black), xMin, yMin, xMax, yMax, rDelta,
495 catch (ThreadAbortException)
497 for (i = 0; i < NrGames; i++)
504 if (Done[i] is
null || !Done[i].WaitOne(0))
517 for (i = 0; i < NrGames; i++)
532 private static void ChaosGameThread(
object P)
534 object[] Parameters = (
object[])P;
535 ManualResetEvent Done = (ManualResetEvent)Parameters[0];
539 double[] SumWeights = (
double[])Parameters[4];
540 FlameState P2 = (FlameState)Parameters[5];
542 bool Preview = (bool)Parameters[7];
543 double Gamma = (double)Parameters[8];
544 double LightFactor = (double)Parameters[9];
548 RunChaosGame(v, Functions, SumWeights, P2, Preview, Gamma, LightFactor, Node);
550 catch (ThreadAbortException)
564 private static void RunChaosGame(
Variables v, FlameFunction[] Functions,
565 double[] SumWeights, FlameState P,
bool Preview,
double Gamma,
double LightFactor,
568 Random Gen =
new Random();
572 int c = Functions.Length;
574 for (i = 0; i < 20; i++)
576 Weight = Gen.NextDouble();
578 while (j < c - 1 && SumWeights[j] <= Weight)
582 if (!f.Operate(P, v))
591 DateTime
Start = DateTime.Now;
592 DateTime NextPreview =
Start.AddSeconds(1);
593 DateTime PrevPreview =
Start;
597 int NextPreviewDeciSeconds = 10;
598 int NrIterationsPerPreview = 4096;
599 int Pos = NrIterationsPerPreview;
601 long PrevNrIterations = 0;
602 long NrIterationsSinceLast;
604 double IterationsPerSeconds;
610 Pos = NrIterationsPerPreview;
612 if (Temp > NextPreview)
614 NextPreview = Temp.AddSeconds(NextPreviewDeciSeconds * 0.1);
615 if (NextPreviewDeciSeconds < 50)
616 NextPreviewDeciSeconds++;
622 Temp2 = DateTime.Now;
624 double d = (Temp2 - Temp).TotalSeconds;
625 double d2 = (Temp - PrevPreview).TotalSeconds;
629 NrIterationsPerPreview <<= 1;
630 if (NrIterationsPerPreview < 0)
631 NrIterationsPerPreview =
int.MaxValue;
635 NrIterations = P.N0 - P.N;
636 NrIterationsSinceLast = NrIterations - PrevNrIterations;
637 IterationsPerSeconds = NrIterationsSinceLast / (Temp - PrevPreview).TotalSeconds;
638 PercentDone = (100 * (1.0 - ((double)P.N) / P.N0));
639 TimeLeft =
new TimeSpan((
long)((Temp -
Start).Ticks * 100 / PercentDone));
640 v.
Status(Node.
Expression, P.N.
ToString() +
" iterations left, " + NrIterations.ToString() +
" iterations done, " + IterationsPerSeconds.ToString(
"F0") +
" iterations/s, " + PercentDone.ToString(
"F1") +
"% done, Time Left: " + TimeLeft.ToString() +
".");
641 PrevNrIterations = NrIterations;
646 Weight = Gen.NextDouble();
648 while (j < c - 1 && SumWeights[j] <= Weight)
652 if (!f.Operate(P, v))
655 while (P.IncHistogram());
663 Weight = Gen.NextDouble();
665 while (j < c - 1 && SumWeights[j] <= Weight)
669 if (!f.Operate(P, v))
672 while (P.IncHistogram());
Script runtime exception.
Class managing a script expression.
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 flame fractal in HSL space. Intensity is mapped along the L-axis. Gamma correction is do...
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, ScriptNode Preview, ScriptNode Parallel, ScriptNode DimX, ScriptNode DimY, int Start, int Length, Expression Expression)
TODO
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, ScriptNode Preview, ScriptNode Parallel, ScriptNode DimX, ScriptNode DimY, ScriptNode SuperSampling, ScriptNode Gamma, ScriptNode LightFactor, ScriptNode Seed, int Start, int Length, Expression Expression)
TODO
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, ScriptNode Preview, ScriptNode Parallel, ScriptNode DimX, ScriptNode DimY, ScriptNode SuperSampling, int Start, int Length, Expression Expression)
TODO
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, ScriptNode Preview, int Start, int Length, Expression Expression)
TODO
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, ScriptNode Preview, ScriptNode Parallel, ScriptNode DimX, int Start, int Length, Expression Expression)
TODO
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, ScriptNode Preview, ScriptNode Parallel, ScriptNode DimX, ScriptNode DimY, ScriptNode SuperSampling, ScriptNode Gamma, int Start, int Length, Expression Expression)
TODO
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, ScriptNode Preview, ScriptNode Parallel, ScriptNode DimX, ScriptNode DimY, ScriptNode SuperSampling, ScriptNode Gamma, ScriptNode LightFactor, int Start, int Length, Expression Expression)
TODO
override IElement Evaluate(IElement[] Arguments, Variables Variables)
TODO
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, int Start, int Length, Expression Expression)
TODO
FlameFractalHsl(ScriptNode xc, ScriptNode yc, ScriptNode dr, ScriptNode N, ScriptNode FlameFunctions, ScriptNode Preview, ScriptNode Parallel, int Start, int Length, Expression Expression)
TODO
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)
TODO
override string[] DefaultArgumentNames
TODO
override string FunctionName
TODO
Calculates a flame fractal in RGBA space. Intensity is calculated along the A-axis....
static void EstimateSize(out double xCenter, out double yCenter, out double rDelta, FlameFunction[] Functions, int Width, int Height, int Seed, long N, Variables Variables, ScriptNode Node)
TODO
Handles bitmap-based graphs.
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.
override string ToString()
Expression Expression
Expression of which the node is a part.
int Start
Start position in script expression.
TextWriter ConsoleOut
Console out interface. Can be used by functions and script to output data to the console.
void Preview(Expression Expression, IElement Result)
Reports a preview of the final result.
bool HandlesPreview
If previews are desired.
bool HandlesStatus
If status messages are desired.
void Status(Expression Expression, string Result)
Reports current status of execution.
void CopyTo(Variables Variables)
Copies available variables to another variable collection.
Basic interface for all types of elements.
Base interface for lambda expressions.
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.