/// <summary> /// Decomposes given matrix into transform operations. /// </summary> /// <param name="matrix">Matrix to decompose.</param> /// <param name="decomposed">Decomposed matrix.</param> /// <returns>The status of the operation.</returns> public static bool TryDecomposeTransform(Matrix matrix, out Decomposed decomposed) { decomposed = default; var determinant = matrix.GetDeterminant(); if (MathUtilities.IsZero(determinant)) { return(false); } var m11 = matrix.M11; var m21 = matrix.M21; var m12 = matrix.M12; var m22 = matrix.M22; // Translation. decomposed.Translate = new Vector(matrix.M31, matrix.M32); // Scale sign. var scaleX = 1d; var scaleY = 1d; if (determinant < 0) { if (m11 < m22) { scaleX *= -1d; } else { scaleY *= -1d; } } // X Scale. scaleX *= Math.Sqrt(m11 * m11 + m12 * m12); m11 /= scaleX; m12 /= scaleX; // XY Shear. double scaledShear = m11 * m21 + m12 * m22; m21 -= m11 * scaledShear; m22 -= m12 * scaledShear; // Y Scale. scaleY *= Math.Sqrt(m21 * m21 + m22 * m22); decomposed.Scale = new Vector(scaleX, scaleY); decomposed.Skew = new Vector(scaledShear / scaleY, 0d); decomposed.Angle = Math.Atan2(m12, m11); return(true); }
public Decomposed Execute( Factor factors, IDivider divider, dynamic algorithm, IUserAlgorithmStrategyProvider strategtProvider ) { factors = Normalize(factors); var decomposed = new Decomposed(); decomposed.Factors.Add(factors); var continueFlag = true; while (continueFlag) { continueFlag = false; var freeTermFactors = (List <int>)GetNumberFactors(decomposed.Factors.Last().Terms.Where(x => x.SymbolsPower == 0).Select(term => term.Number).FirstOrDefault(), algorithm, strategtProvider ); freeTermFactors.ForEach(coefficent => { var dividedPart = divider.Divide(decomposed.Factors.Last(), -coefficent); if (dividedPart != null) { Console.WriteLine(decomposed); var newdividerFactor = new Factor(); newdividerFactor.Terms = new List <Term>() { new Term { Number = 1, Sign = Sign.Plus, Symbol = 'x', SymbolsPower = 1 }, new Term { Number = Math.Abs(coefficent), Sign = (coefficent >= 0) ? Sign.Minus : Sign.Plus, SymbolsPower = 1 } }; decomposed.Factors.Insert(0, newdividerFactor); decomposed.Factors[decomposed.Factors.Count() - 1] = dividedPart; continueFlag = true; } }); } return(decomposed); }
public void Write(Decomposed decomposed, string path) { var mathMlTerm = Converter.MathMLConvert(decomposed); var formatter = new XmlSerializer(typeof(MathMlTerm)); using (var fileStream = new FileStream(path, FileMode.Create)) { formatter.Serialize(fileStream, mathMlTerm); } }
public static MathMlTerm MathMLConvert(Decomposed decomposed) { var math = new MathElement(); decomposed.Factors.ForEach(factor => { var mfenced = new MfencedElement(); factor.Terms.ForEach(term => { var operation = (term.Sign == Sign.Plus) ? "+" : "-"; mfenced.Terms.Add(operation); mfenced.Terms.Add(term.Number); //number if (term.Symbol != null && term.Symbol != default(char)) { var insideOperation = "⁢"; mfenced.Terms.Add(insideOperation); //number * var insideMsup = new MsupElement(); var symbolicValue = term.Symbol.Value; var symbolPower = term.SymbolsPower; insideMsup.Terms.Add(symbolicValue); insideMsup.Terms.Add(symbolPower); mfenced.Terms.Add(insideMsup);//x^power } }); math.Terms.Add(mfenced); }); return(math); }