diff --git a/apps/calculation/additional_outputs/trigonometry_list_controller.cpp b/apps/calculation/additional_outputs/trigonometry_list_controller.cpp index b8bdcb076..354cbc739 100644 --- a/apps/calculation/additional_outputs/trigonometry_list_controller.cpp +++ b/apps/calculation/additional_outputs/trigonometry_list_controller.cpp @@ -1,16 +1,63 @@ #include "trigonometry_list_controller.h" #include "../app.h" +#include +#include "../../shared/poincare_helpers.h" using namespace Poincare; namespace Calculation { -void TrigonometryListController::setExpression(Poincare::Expression e) { +static constexpr int s_fullCircle[] = { + 360, + 2, + 400 +}; + +Poincare::Constant toConstant(Expression e) { + return static_cast(e); +} + +void TrigonometryListController::setExpression(Expression e) { assert(e.type() == ExpressionNode::Type::Cosine || e.type() == ExpressionNode::Type::Sine); - IllustratedListController::setExpression(e.childAtIndex(0)); + + Poincare::Context * context = App::app()->localContext(); + Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); + Preferences::AngleUnit angleUnit = preferences->angleUnit(); + + Expression angleExpression = e.childAtIndex(0); + + Shared::PoincareHelpers::Reduce(&angleExpression, context, Poincare::ExpressionNode::ReductionTarget::SystemForAnalysis); + + if ((angleUnit == Preferences::AngleUnit::Radian + && angleExpression.type() == ExpressionNode::Type::Multiplication + && angleExpression.numberOfChildren() == 2 + && angleExpression.childAtIndex(1).type() == ExpressionNode::Type::Constant + && toConstant(angleExpression.childAtIndex(1)).isPi() + && angleExpression.childAtIndex(0).type() == ExpressionNode::Type::Rational) + || ((angleUnit == Preferences::AngleUnit::Degree || angleUnit == Preferences::AngleUnit::Gradian) + && angleExpression.type() == ExpressionNode::Type::Rational)) { + + Expression extracted = angleUnit == Preferences::AngleUnit::Radian ? angleExpression.childAtIndex(0) : angleExpression; + Rational r = static_cast(extracted); + + Integer denominator = Integer::Multiplication(r.integerDenominator(), Integer(s_fullCircle[(int) angleUnit])); + IntegerDivision division = Integer::Division(r.signedIntegerNumerator(), denominator); + + Integer remainder = division.remainder; + + Expression newAngle; + Integer rDenominator = r.integerDenominator(); + Rational newCoefficient = Rational::Builder(remainder, rDenominator); + if (angleUnit == Preferences::AngleUnit::Radian) { + angleExpression = Multiplication::Builder(newCoefficient, angleExpression.childAtIndex(1)); + } else { + angleExpression = newCoefficient; + } + } + + IllustratedListController::setExpression(angleExpression); // Fill calculation store - Poincare::Context * context = App::app()->localContext(); m_calculationStore.push("sin(θ)", context, CalculationHeight); m_calculationStore.push("cos(θ)", context, CalculationHeight); m_calculationStore.push("θ", context, CalculationHeight); diff --git a/apps/calculation/calculation_store.cpp b/apps/calculation/calculation_store.cpp index 5293474c9..72bc57d34 100644 --- a/apps/calculation/calculation_store.cpp +++ b/apps/calculation/calculation_store.cpp @@ -237,7 +237,7 @@ Shared::ExpiringPointer CalculationStore::emptyStoreAndPushUndef(Co // Recompute memoized pointers to the calculations after index i void CalculationStore::recomputeMemoizedPointersAfterCalculationIndex(int index) { - assert(index < numberOfCalculations()); + assert(index < m_numberOfCalculations); // Clear pointer and recompute new ones Calculation * c = realCalculationAtIndex(index).pointer(); Calculation * nextCalc;