diff --git a/apps/calculation/additional_outputs/trigonometry_graph_cell.cpp b/apps/calculation/additional_outputs/trigonometry_graph_cell.cpp index 636ce588a..fe5487e0a 100644 --- a/apps/calculation/additional_outputs/trigonometry_graph_cell.cpp +++ b/apps/calculation/additional_outputs/trigonometry_graph_cell.cpp @@ -8,7 +8,8 @@ namespace Calculation { TrigonometryGraphView::TrigonometryGraphView(TrigonometryModel * model) : CurveView(model), - m_model(model) + m_model(model), + m_shouldDisplayTan(false) { } @@ -22,17 +23,33 @@ void TrigonometryGraphView::drawRect(KDContext * ctx, KDRect rect) const { drawCurve(ctx, rect, 0.0f, 2.0f*M_PI, M_PI/180.0f, [](float t, void * model, void * context) { return Poincare::Coordinate2D(std::cos(t), std::sin(t)); }, nullptr, nullptr, true, Palette::SecondaryText, false); - // Draw dashed segment to indicate sine and cosine - drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, c, 0.0f, s, Palette::CalculationTrigoAndComplexForeground, 1, 3); - drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, s, 0.0f, c, Palette::CalculationTrigoAndComplexForeground, 1, 3); + + if (!m_shouldDisplayTan) { + // Draw dashed segment to indicate sine and cosine + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, c, 0.0f, s, Palette::CalculationTrigoAndComplexForeground, 1, 3); + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, s, 0.0f, c, Palette::CalculationTrigoAndComplexForeground, 1, 3); + } + + if (m_shouldDisplayTan) { + float t = std::tan(m_model->angle()); + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Vertical, 1.0f, m_model->yMin(), m_model->yMax(), Palette::SecondaryText, 2); + drawSegment(ctx, rect, 0.0f, 0.0f, 1.0f, t, Palette::SecondaryText, false); + drawDot(ctx, rect, 1.0f, t, Palette::CalculationTrigoAndComplexForeground, Size::Large); + drawLabel(ctx, rect, 0.0f, t, "tan(θ)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::Before, CurveView::RelativePosition::None); + drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, t, 0.0f, 1.0f, Palette::CalculationTrigoAndComplexForeground, 1, 3); + } + // Draw angle position on the circle - drawDot(ctx, rect, c, s, Palette::CalculationTrigoAndComplexForeground, Size::Large); + drawDot(ctx, rect, c, s, m_shouldDisplayTan ? Palette::SecondaryText : Palette::CalculationTrigoAndComplexForeground, m_shouldDisplayTan ? Size::Tiny : Size::Large); // Draw graduations drawLabelsAndGraduations(ctx, rect, Axis::Vertical, false, true); drawLabelsAndGraduations(ctx, rect, Axis::Horizontal, false, true); - // Draw labels - drawLabel(ctx, rect, 0.0f, s, "sin(θ)", Palette::CalculationTrigoAndComplexForeground, c >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None); - drawLabel(ctx, rect, c, 0.0f, "cos(θ)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, s >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After); + + if (!m_shouldDisplayTan) { + // Draw labels + drawLabel(ctx, rect, 0.0f, s, "sin(θ)", Palette::CalculationTrigoAndComplexForeground, c >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After, CurveView::RelativePosition::None); + drawLabel(ctx, rect, c, 0.0f, "cos(θ)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, s >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After); + } } } diff --git a/apps/calculation/additional_outputs/trigonometry_graph_cell.h b/apps/calculation/additional_outputs/trigonometry_graph_cell.h index aea81926a..92fccd8ae 100644 --- a/apps/calculation/additional_outputs/trigonometry_graph_cell.h +++ b/apps/calculation/additional_outputs/trigonometry_graph_cell.h @@ -11,13 +11,16 @@ class TrigonometryGraphView : public Shared::CurveView { public: TrigonometryGraphView(TrigonometryModel * model); void drawRect(KDContext * ctx, KDRect rect) const override; + void setShouldDisplayTan(bool shouldDisplayTan) { m_shouldDisplayTan = shouldDisplayTan; }; private: TrigonometryModel * m_model; + bool m_shouldDisplayTan; }; class TrigonometryGraphCell : public IllustrationCell { public: TrigonometryGraphCell(TrigonometryModel * model) : m_view(model) {} + void setShouldDisplayTan(bool shouldDisplayTan) { m_view.setShouldDisplayTan(shouldDisplayTan); }; private: View * view() override { return &m_view; } TrigonometryGraphView m_view; diff --git a/apps/calculation/additional_outputs/trigonometry_list_controller.cpp b/apps/calculation/additional_outputs/trigonometry_list_controller.cpp index 354cbc739..bdb612006 100644 --- a/apps/calculation/additional_outputs/trigonometry_list_controller.cpp +++ b/apps/calculation/additional_outputs/trigonometry_list_controller.cpp @@ -18,7 +18,10 @@ Poincare::Constant toConstant(Expression e) { } void TrigonometryListController::setExpression(Expression e) { - assert(e.type() == ExpressionNode::Type::Cosine || e.type() == ExpressionNode::Type::Sine); + assert(e.type() == ExpressionNode::Type::Cosine || e.type() == ExpressionNode::Type::Sine || e.type() == ExpressionNode::Type::Tangent); + bool shouldDisplayTan = e.type() == ExpressionNode::Type::Tangent; + m_graphCell.setShouldDisplayTan(shouldDisplayTan); + m_model.setShouldDisplayTan(shouldDisplayTan); Poincare::Context * context = App::app()->localContext(); Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); @@ -58,6 +61,7 @@ void TrigonometryListController::setExpression(Expression e) { IllustratedListController::setExpression(angleExpression); // Fill calculation store + m_calculationStore.push("tan(θ)", context, CalculationHeight); m_calculationStore.push("sin(θ)", context, CalculationHeight); m_calculationStore.push("cos(θ)", context, CalculationHeight); m_calculationStore.push("θ", context, CalculationHeight); diff --git a/apps/calculation/additional_outputs/trigonometry_model.cpp b/apps/calculation/additional_outputs/trigonometry_model.cpp index ef7c708c3..8b61bac8d 100644 --- a/apps/calculation/additional_outputs/trigonometry_model.cpp +++ b/apps/calculation/additional_outputs/trigonometry_model.cpp @@ -8,4 +8,22 @@ TrigonometryModel::TrigonometryModel() : { } +float TrigonometryModel::yMin() const { + if (m_shouldDisplayTan) { + return -1.1f; + } + return yCenter() - yHalfRange(); +} + +float TrigonometryModel::yMax() const { + if (m_shouldDisplayTan) { + float t = std::tan(angle()); + if (t <= 1.2f) { + return 1.2f; + } + return 1.2f * std::tan(angle()); + } + return yCenter() + yHalfRange(); +} + } diff --git a/apps/calculation/additional_outputs/trigonometry_model.h b/apps/calculation/additional_outputs/trigonometry_model.h index c299565a8..f53ebbd3c 100644 --- a/apps/calculation/additional_outputs/trigonometry_model.h +++ b/apps/calculation/additional_outputs/trigonometry_model.h @@ -14,11 +14,12 @@ public: // CurveViewRange float xMin() const override { return -k_xHalfRange; } float xMax() const override { return k_xHalfRange; } - float yMin() const override { return yCenter() - yHalfRange(); } - float yMax() const override { return yCenter() + yHalfRange(); } + float yMin() const override; + float yMax() const override; void setAngle(float f) { m_angle = f; } float angle() const { return m_angle*(float)M_PI/(float)Poincare::Trigonometry::PiInAngleUnit(Poincare::Preferences::sharedPreferences()->angleUnit()); } + void setShouldDisplayTan(bool shouldDisplayTan) { m_shouldDisplayTan = shouldDisplayTan; } private: constexpr static float k_xHalfRange = 2.1f; // We center the yRange around the semi-circle where the angle is @@ -33,6 +34,7 @@ private: float yHalfRange() const { return IllustratedListController::k_illustrationHeight*k_xHalfRange/(Ion::Display::Width - Metric::PopUpRightMargin - Metric::PopUpLeftMargin); } float m_angle; + bool m_shouldDisplayTan; }; }