/// <summary> /// Draws the graph on a canvas. /// </summary> /// <param name="Canvas">Canvas to draw on.</param> /// <param name="Points">Points to draw.</param> /// <param name="Parameters">Graph-specific parameters.</param> /// <param name="PrevPoints">Points of previous graph of same type (if available), null (if not available).</param> /// <param name="PrevParameters">Parameters of previous graph of same type (if available), null (if not available).</param> /// <param name="DrawingArea">Current drawing area.</param> public void DrawGraph(SKCanvas Canvas, SKPoint[] Points, object[] Parameters, SKPoint[] PrevPoints, object[] PrevParameters, DrawingArea DrawingArea) { SKPaint Brush = null; SKPath Path = null; try { Brush = new SKPaint() { Style = SKPaintStyle.Fill, Color = Graph.ToColor(Parameters[0]) }; Path = new SKPath(); Path = Plot2DCurvePainter.CreateSpline(Points); if (PrevPoints is null) { IElement Zero; ISet Set = DrawingArea.MinY.AssociatedSet; if (Set is IGroup Group) { Zero = Group.AdditiveIdentity; } else { Zero = new DoubleNumber(0); } IVector XAxis = VectorDefinition.Encapsulate(new IElement[] { DrawingArea.MinX, DrawingArea.MaxX }, false, null) as IVector; IVector YAxis = VectorDefinition.Encapsulate(new IElement[] { Zero, Zero }, false, null) as IVector; PrevPoints = DrawingArea.Scale(XAxis, YAxis); if (DrawingArea.MinX is StringValue && DrawingArea.MaxX is StringValue) { PrevPoints[0].X = Points[0].X; PrevPoints[1].X = Points[Points.Length - 1].X; } } PrevPoints = (SKPoint[])PrevPoints.Clone(); Array.Reverse(PrevPoints); Plot2DCurvePainter.CreateSpline(Path, PrevPoints); Path.LineTo(Points[0]); Canvas.DrawPath(Path, Brush); } finally { Brush?.Dispose(); Path?.Dispose(); } }
/// <summary> /// Evaluates the node, using the variables provided in the <paramref name="Variables"/> collection. /// </summary> /// <param name="Variables">Variables collection.</param> /// <returns>Result.</returns> public override IElement Evaluate(Variables Variables) { LinkedList <IElement> List = new LinkedList <IElement>(); int c = 0; foreach (ScriptNode E in this.elements) { if (E == null) { List.AddLast((IElement)null); } else { List.AddLast(E.Evaluate(Variables)); } c++; } switch (c) { case 0: return(ObjectValue.Null); case 1: return(List.First.Value); case 2: DoubleNumber Re, Im; if ((Re = List.First.Value as DoubleNumber) != null && (Im = List.First.Next.Value as DoubleNumber) != null) { return(new ComplexNumber(new Complex(Re.Value, Im.Value))); } break; } return(VectorDefinition.Encapsulate(List, true, this)); }
/// <summary> /// Encapsulates a set of elements into a similar structure as that provided by the current element. /// </summary> /// <param name="Elements">New set of child elements, not necessarily of the same type as the child elements of the current object.</param> /// <param name="Node">Script node from where the encapsulation is done.</param> /// <returns>Encapsulated object of similar type as the current object.</returns> public override IElement Encapsulate(ICollection <IElement> Elements, ScriptNode Node) { return(VectorDefinition.Encapsulate(Elements, true, Node)); }
private void DrawGraph(SKCanvas Canvas, SKPoint[] Points, object[] Parameters, SKPoint[] PrevPoints, object[] PrevParameters, DrawingArea DrawingArea) { SKPaint Brush = null; SKPath Path = null; bool First = true; try { Brush = new SKPaint() { Style = SKPaintStyle.Fill, Color = Graph.ToColor(Parameters[0]) }; Path = new SKPath(); foreach (SKPoint Point in Points) { if (First) { First = false; Path.MoveTo(Point); } else { Path.LineTo(Point); } } if (PrevPoints is null) { IElement Zero; ISet Set = DrawingArea.MinY.AssociatedSet; if (Set is IGroup Group) { Zero = Group.AdditiveIdentity; } else { Zero = new DoubleNumber(0); } IVector XAxis = VectorDefinition.Encapsulate(new IElement[] { DrawingArea.MinX, DrawingArea.MaxX }, false, this) as IVector; IVector YAxis = VectorDefinition.Encapsulate(new IElement[] { Zero, Zero }, false, this) as IVector; PrevPoints = DrawingArea.Scale(XAxis, YAxis); if (DrawingArea.MinX is StringValue && DrawingArea.MaxX is StringValue) { PrevPoints[0].X = Points[0].X; PrevPoints[1].X = Points[Points.Length - 1].X; } } int i = PrevPoints.Length; while (--i >= 0) { Path.LineTo(PrevPoints[i]); } Path.LineTo(Points[0]); Canvas.DrawPath(Path, Brush); } finally { if (Brush != null) { Brush.Dispose(); } if (Path != null) { Path.Dispose(); } } }
internal static IElement EncapsulateToVector(ICollection <IElement> Elements, ScriptNode Node) { return(VectorDefinition.Encapsulate(Elements, true, Node)); }
private IElement EvaluateCanonicalExtension(IElement[] Arguments, Variables Variables) { ICollection <IElement> ChildElements; IEnumerator <IElement>[] e = new IEnumerator <IElement> [this.nrArguments]; IElement Argument; Encapsulation Encapsulation = null; IMatrix M; ISet S; IVectorSpaceElement V; int Dimension = -1; int i, j; for (i = 0; i < this.nrArguments; i++) { Argument = Arguments[i]; switch (this.argumentTypes[i]) { case ArgumentType.Normal: e[i] = null; break; case ArgumentType.Scalar: if (Argument.IsScalar) { e[i] = null; } else { ChildElements = Argument.ChildElements; if (Dimension < 0) { Dimension = ChildElements.Count; } else if (ChildElements.Count != Dimension) { throw new ScriptRuntimeException("Argument dimensions not consistent.", this); } e[i] = ChildElements.GetEnumerator(); if (Encapsulation == null) { Encapsulation = Argument.Encapsulate; } } break; case ArgumentType.Vector: if (Argument is IVectorSpaceElement) { e[i] = null; } else if ((M = Argument as IMatrix) != null) { if (Dimension < 0) { Dimension = M.Rows; } else if (M.Rows != Dimension) { throw new ScriptRuntimeException("Argument dimensions not consistent.", this); } LinkedList <IElement> Vectors = new LinkedList <IElement>(); for (j = 0; j < Dimension; j++) { Vectors.AddLast(M.GetRow(j)); } e[i] = Vectors.GetEnumerator(); if (Encapsulation == null) { Encapsulation = EncapsulateToVector; } } else if ((S = Argument as ISet) != null) { int?Size = S.Size; if (!Size.HasValue) { throw new ScriptRuntimeException("Argument dimensions not consistent.", this); } if (Dimension < 0) { Dimension = Size.Value; } else if (Size.Value != Dimension) { throw new ScriptRuntimeException("Argument dimensions not consistent.", this); } e[i] = S.ChildElements.GetEnumerator(); if (Encapsulation == null) { Encapsulation = Argument.Encapsulate; } } else { Arguments[i] = VectorDefinition.Encapsulate(new IElement[] { Argument }, false, this); e[i] = null; } break; case ArgumentType.Set: if (Argument is ISet) { e[i] = null; } else if ((V = Argument as IVectorSpaceElement) != null) { Arguments[i] = SetDefinition.Encapsulate(V.ChildElements, this); e[i] = null; } else if ((M = Argument as IMatrix) != null) { if (Dimension < 0) { Dimension = M.Rows; } else if (M.Rows != Dimension) { throw new ScriptRuntimeException("Argument dimensions not consistent.", this); } LinkedList <IElement> Vectors = new LinkedList <IElement>(); for (j = 0; j < Dimension; j++) { Vectors.AddLast(M.GetRow(j)); } Arguments[i] = Argument = SetDefinition.Encapsulate(Vectors, this); ChildElements = Argument.ChildElements; e[i] = ChildElements.GetEnumerator(); if (Encapsulation == null) { Encapsulation = EncapsulateToVector; } } else { Arguments[i] = SetDefinition.Encapsulate(new IElement[] { Argument }, this); e[i] = null; } break; case ArgumentType.Matrix: if (Argument is IMatrix) { e[i] = null; } else if ((V = Argument as IVectorSpaceElement) != null) { Arguments[i] = MatrixDefinition.Encapsulate(V.ChildElements, 1, V.Dimension, this); e[i] = null; } else if ((S = Argument as ISet) != null) { int?Size = S.Size; if (!Size.HasValue) { throw new ScriptRuntimeException("Argument dimensions not consistent.", this); } if (Dimension < 0) { Dimension = Size.Value; } else if (Size.Value != Dimension) { throw new ScriptRuntimeException("Argument dimensions not consistent.", this); } e[i] = S.ChildElements.GetEnumerator(); if (Encapsulation == null) { Encapsulation = Argument.Encapsulate; } } else { Arguments[i] = MatrixDefinition.Encapsulate(new IElement[] { Argument }, 1, 1, this); e[i] = null; } break; default: throw new ScriptRuntimeException("Unhandled argument type.", this); } } if (Encapsulation != null) { LinkedList <IElement> Result = new LinkedList <IElement>(); IElement[] Arguments2 = new IElement[this.nrArguments]; for (j = 0; j < Dimension; j++) { for (i = 0; i < this.nrArguments; i++) { if (e[i] == null || !e[i].MoveNext()) { Arguments2[i] = Arguments[i]; } else { Arguments2[i] = e[i].Current; } } Result.AddLast(this.EvaluateCanonicalExtension(Arguments2, Variables)); } return(Encapsulation(Result, this)); } else { for (i = 0; i < this.nrArguments; i++) { Variables[this.argumentNames[i]] = Arguments[i]; } try { return(this.op.Evaluate(Variables)); } catch (ScriptReturnValueException ex) { return(ex.ReturnValue); } } }
/// <summary> /// Tries to add an element to the current element, from the right. /// </summary> /// <param name="Element">Element to add.</param> /// <returns>Result, if understood, null otherwise.</returns> public override ISemiGroupElement AddRight(ISemiGroupElement Element) { if (this.x.First == null) { return(Element); } Graph2D G = Element as Graph2D; if (G == null) { return(null); } if (G.x.First == null) { return(this); } Graph2D Result = new Graph2D() { axisTypeX = this.axisTypeX, axisTypeY = this.axisTypeY }; foreach (IVector v in this.x) { Result.x.AddLast(v); } foreach (IVector v in this.y) { Result.y.AddLast(v); } foreach (DrawCallback Callback in this.callbacks) { Result.callbacks.AddLast(Callback); } foreach (object[] P in this.parameters) { Result.parameters.AddLast(P); } foreach (IVector v in G.x) { if (v.GetType() != this.axisTypeX) { throw new ScriptException("Incompatible types of series."); } Result.x.AddLast(v); } foreach (IVector v in G.y) { if (v.GetType() != this.axisTypeY) { throw new ScriptException("Incompatible types of series."); } Result.y.AddLast(v); } foreach (DrawCallback Callback in G.callbacks) { Result.callbacks.AddLast(Callback); } foreach (object[] P in G.parameters) { Result.parameters.AddLast(P); } Result.minX = Min.CalcMin((IVector)VectorDefinition.Encapsulate(new IElement[] { this.minX, G.minX }, false, null), null); Result.maxX = Max.CalcMax((IVector)VectorDefinition.Encapsulate(new IElement[] { this.maxX, G.maxX }, false, null), null); Result.minY = Min.CalcMin((IVector)VectorDefinition.Encapsulate(new IElement[] { this.minY, G.minY }, false, null), null); Result.maxY = Max.CalcMax((IVector)VectorDefinition.Encapsulate(new IElement[] { this.maxY, G.maxY }, false, null), null); Result.showXAxis |= G.showXAxis; Result.showYAxis |= G.showYAxis; return(Result); }
/// <summary> /// Evaluates the function. /// </summary> /// <param name="Argument">Function argument.</param> /// <param name="Variables">Variables collection.</param> /// <returns>Function result.</returns> public override IElement Evaluate(IElement Argument, Variables Variables) { if (Argument is IVector Vector) { if (Vector is DoubleVector DoubleVector) { return(this.EvaluateVector(DoubleVector, Variables)); } if (Vector is ComplexVector ComplexVector) { return(this.EvaluateVector(ComplexVector, Variables)); } if (Vector is BooleanVector BooleanVector) { return(this.EvaluateVector(BooleanVector, Variables)); } return(this.EvaluateVector(Vector, Variables)); } else { if (Argument is IMatrix Matrix) { LinkedList <IElement> Elements = new LinkedList <IElement>(); int i, c = Matrix.Rows; if (Matrix is DoubleMatrix) { for (i = 0; i < c; i++) { Elements.AddLast(this.Evaluate((DoubleVector)Matrix.GetRow(i), Variables)); } } else if (Matrix is ComplexMatrix) { for (i = 0; i < c; i++) { Elements.AddLast(this.Evaluate((ComplexVector)Matrix.GetRow(i), Variables)); } } else if (Matrix is BooleanMatrix) { for (i = 0; i < c; i++) { Elements.AddLast(this.Evaluate((BooleanVector)Matrix.GetRow(i), Variables)); } } else { for (i = 0; i < c; i++) { Elements.AddLast(this.Evaluate(Matrix.GetRow(i), Variables)); } } return(Argument.Encapsulate(Elements, this)); } else { if (Argument is ISet Set) { LinkedList <IElement> Elements = new LinkedList <IElement>(); foreach (IElement E in Set.ChildElements) { Elements.AddLast(this.Evaluate(E, Variables)); } return(Argument.Encapsulate(Elements, this)); } else { return(this.EvaluateVector((IVector)VectorDefinition.Encapsulate(new IElement[] { Argument }, false, this), Variables)); } } } }