public BladeDecomposition AnalyzeBlade(Operand operand, Context context) { BladeDecomposition decomposition; decomposition.weight = null; decomposition.center = null; decomposition.radius = null; decomposition.normal = null; decomposition.analysisList = new List <string>(); using (var pushPopper = new ContextPushPopper(context)) { int grade = operand.Grade; if (grade < 0) { decomposition.analysisList.Add("Could not identify grade of given element."); } else { OuterProduct blade = null; try { blade = FactorBlade.Factor(operand, context); } catch (MathException) { } if (blade == null) { decomposition.analysisList.Add("The given element was not a blade."); } else { context.operandStorage.SetStorage("__blade__", operand); Evaluate("del(@weight, @center, @radius, @normal)", context); switch (grade) { case 0: { if (operand.IsAdditiveIdentity) { decomposition.analysisList.Add("The blade is all of space."); } else { decomposition.analysisList.Add("The blade is the empty set."); } break; } case 1: { decomposition.weight = Evaluate("@weight = mag(ni . @__blade__)", context).output; if (decomposition.weight.IsAdditiveIdentity) { decomposition.analysisList.Add("The blade is a plane."); decomposition.weight = Evaluate("@weight = mag(no . ni ^ @__blade__)", context).output; Evaluate("@__blade__ = @__blade__ / @weight", context); decomposition.normal = Evaluate("@normal = -no . ni ^ @__blade__", context).output; decomposition.center = Evaluate("@center = (-no . @__blade__) * @normal", context).output; } else { Evaluate("@__blade__ = @__blade__ / @weight", context); decomposition.center = Evaluate("@center = ni^no . ni^no ^ @__blade__", context).output; Operand squareRadius = Evaluate("@__square_radius__ = @__blade__ . @__blade__", context).output; if (squareRadius.IsAdditiveIdentity) { decomposition.analysisList.Add("The blade is a point."); } else if (!(squareRadius is NumericScalar numericScalar)) { decomposition.analysisList.Add("The blade is a sphere."); decomposition.radius = Evaluate("@radius = sqrt(@__square_radius__)", context).output; }
public VersorDecomposition AnalyzeVersor(Operand operand, Context context) { VersorDecomposition decomposition; decomposition.analysisList = new List <string>(); using (var pushPopper = new ContextPushPopper(context)) { int grade = operand.Grade; if (grade == 0) { if (operand.IsAdditiveIdentity) { decomposition.analysisList.Add("Zero is not a versor because it is not invertible."); } else { decomposition.analysisList.Add("Non-zero scalars act as the identity transformation."); } } else { GeometricProduct versor = null; try { versor = FactorVersor.Factor(operand, context); } catch (MathException) { } if (versor == null) { decomposition.analysisList.Add("The given element was not a versor."); } else { // The reflections and rotations of conformal space give us the conformal transformations in the embedded 3D euclidean sub-space. int i = versor.operandList.Count - 1; while (i >= 0) { if (i - 1 >= 0 && AnalyzeRotation(versor.operandList[i - 1], versor.operandList[i], ref decomposition, context)) { i -= 2; } else if (AnalyzeReflection(versor.operandList[i], ref decomposition, context)) { i--; } else { decomposition.analysisList.Add("Failed to recognize transformation performed by vector."); i--; } } } } } return(decomposition); }