Merge pull request #254 from RedGl0w/additional_result_trigo

Changes to the trigonometry additional result
This commit is contained in:
Yaya-Cout
2025-11-05 17:17:44 +00:00
committed by GitHub
10 changed files with 70 additions and 22 deletions

View File

@@ -8,7 +8,8 @@ namespace Calculation {
TrigonometryGraphView::TrigonometryGraphView(TrigonometryModel * model) : TrigonometryGraphView::TrigonometryGraphView(TrigonometryModel * model) :
CurveView(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) { drawCurve(ctx, rect, 0.0f, 2.0f*M_PI, M_PI/180.0f, [](float t, void * model, void * context) {
return Poincare::Coordinate2D<float>(std::cos(t), std::sin(t)); return Poincare::Coordinate2D<float>(std::cos(t), std::sin(t));
}, nullptr, nullptr, true, Palette::SecondaryText, false); }, 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); if (!m_shouldDisplayTan) {
drawHorizontalOrVerticalSegment(ctx, rect, Axis::Horizontal, s, 0.0f, c, Palette::CalculationTrigoAndComplexForeground, 1, 3); // 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 // 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 // Draw graduations
drawLabelsAndGraduations(ctx, rect, Axis::Vertical, false, true); drawLabelsAndGraduations(ctx, rect, Axis::Vertical, false, true);
drawLabelsAndGraduations(ctx, rect, Axis::Horizontal, 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); if (!m_shouldDisplayTan) {
drawLabel(ctx, rect, c, 0.0f, "cos(θ)", Palette::CalculationTrigoAndComplexForeground, CurveView::RelativePosition::None, s >= 0.0f ? CurveView::RelativePosition::Before : CurveView::RelativePosition::After); // 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);
}
} }
} }

View File

@@ -11,13 +11,16 @@ class TrigonometryGraphView : public Shared::CurveView {
public: public:
TrigonometryGraphView(TrigonometryModel * model); TrigonometryGraphView(TrigonometryModel * model);
void drawRect(KDContext * ctx, KDRect rect) const override; void drawRect(KDContext * ctx, KDRect rect) const override;
void setShouldDisplayTan(bool shouldDisplayTan) { m_shouldDisplayTan = shouldDisplayTan; };
private: private:
TrigonometryModel * m_model; TrigonometryModel * m_model;
bool m_shouldDisplayTan;
}; };
class TrigonometryGraphCell : public IllustrationCell { class TrigonometryGraphCell : public IllustrationCell {
public: public:
TrigonometryGraphCell(TrigonometryModel * model) : m_view(model) {} TrigonometryGraphCell(TrigonometryModel * model) : m_view(model) {}
void setShouldDisplayTan(bool shouldDisplayTan) { m_view.setShouldDisplayTan(shouldDisplayTan); };
private: private:
View * view() override { return &m_view; } View * view() override { return &m_view; }
TrigonometryGraphView m_view; TrigonometryGraphView m_view;

View File

@@ -18,7 +18,10 @@ Poincare::Constant toConstant(Expression e) {
} }
void TrigonometryListController::setExpression(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::Context * context = App::app()->localContext();
Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences(); Poincare::Preferences * preferences = Poincare::Preferences::sharedPreferences();
@@ -58,6 +61,7 @@ void TrigonometryListController::setExpression(Expression e) {
IllustratedListController::setExpression(angleExpression); IllustratedListController::setExpression(angleExpression);
// Fill calculation store // Fill calculation store
m_calculationStore.push("tan(θ)", context, CalculationHeight);
m_calculationStore.push("sin(θ)", context, CalculationHeight); m_calculationStore.push("sin(θ)", context, CalculationHeight);
m_calculationStore.push("cos(θ)", context, CalculationHeight); m_calculationStore.push("cos(θ)", context, CalculationHeight);
m_calculationStore.push("θ", context, CalculationHeight); m_calculationStore.push("θ", context, CalculationHeight);

View File

@@ -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();
}
} }

View File

@@ -14,11 +14,12 @@ public:
// CurveViewRange // CurveViewRange
float xMin() const override { return -k_xHalfRange; } float xMin() const override { return -k_xHalfRange; }
float xMax() const override { return k_xHalfRange; } float xMax() const override { return k_xHalfRange; }
float yMin() const override { return yCenter() - yHalfRange(); } float yMin() const override;
float yMax() const override { return yCenter() + yHalfRange(); } float yMax() const override;
void setAngle(float f) { m_angle = f; } void setAngle(float f) { m_angle = f; }
float angle() const { return m_angle*(float)M_PI/(float)Poincare::Trigonometry::PiInAngleUnit(Poincare::Preferences::sharedPreferences()->angleUnit()); } 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: private:
constexpr static float k_xHalfRange = 2.1f; constexpr static float k_xHalfRange = 2.1f;
// We center the yRange around the semi-circle where the angle is // 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 yHalfRange() const { return IllustratedListController::k_illustrationHeight*k_xHalfRange/(Ion::Display::Width - Metric::PopUpRightMargin - Metric::PopUpLeftMargin); }
float m_angle; float m_angle;
bool m_shouldDisplayTan;
}; };
} }

View File

@@ -251,8 +251,11 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
* - > input: 2cos(2) - cos(2) * - > input: 2cos(2) - cos(2)
* > output: cos(2) * > output: cos(2)
*/ */
if (input().isDefinedCosineOrSine(context, complexFormat, preferences->angleUnit()) || o.isDefinedCosineOrSine(context, complexFormat, preferences->angleUnit())) { if (i.isDefinedCosineOrSineOrTangent(context, complexFormat, preferences->angleUnit())) {
return AdditionalInformationType::Trigonometry; return AdditionalInformationType::TrigonometryInput;
}
if (o.isDefinedCosineOrSineOrTangent(context, complexFormat, preferences->angleUnit())) {
return AdditionalInformationType::TrigonometryOutput;
} }
if (o.hasUnit()) { if (o.hasUnit()) {
Expression unit; Expression unit;

View File

@@ -40,7 +40,8 @@ public:
Integer, Integer,
Rational, Rational,
SecondDegree, SecondDegree,
Trigonometry, TrigonometryInput,
TrigonometryOutput,
Unit, Unit,
Matrix, Matrix,
Complex Complex

View File

@@ -103,12 +103,12 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
vc = &m_complexController; vc = &m_complexController;
} else if (additionalInfoType == Calculation::AdditionalInformationType::SecondDegree) { } else if (additionalInfoType == Calculation::AdditionalInformationType::SecondDegree) {
vc = &m_secondDegreeController; vc = &m_secondDegreeController;
} else if (additionalInfoType == Calculation::AdditionalInformationType::Trigonometry) { } else if (additionalInfoType == Calculation::AdditionalInformationType::TrigonometryInput) {
vc = &m_trigonometryController; vc = &m_trigonometryController;
// Find which of the input or output is the cosine/sine e = calculationAtIndex(focusRow)->input();
ExpressionNode::Type t = e.type(); } else if (additionalInfoType == Calculation::AdditionalInformationType::TrigonometryOutput) {
e = t == ExpressionNode::Type::Cosine || t == ExpressionNode::Type::Sine ? e : calculationAtIndex(focusRow)->input(); vc = &m_trigonometryController;
} else if (additionalInfoType == Calculation::AdditionalInformationType::Integer) { } else if (additionalInfoType == Calculation::AdditionalInformationType::Integer) {
vc = &m_integerController; vc = &m_integerController;
} else if (additionalInfoType == Calculation::AdditionalInformationType::Rational) { } else if (additionalInfoType == Calculation::AdditionalInformationType::Rational) {
vc = &m_rationalController; vc = &m_rationalController;

View File

@@ -183,7 +183,7 @@ public:
bool isRationalOne() const; bool isRationalOne() const;
bool isRandom() const { return node()->isRandom(); } bool isRandom() const { return node()->isRandom(); }
bool isParameteredExpression() const { return node()->isParameteredExpression(); } bool isParameteredExpression() const { return node()->isParameteredExpression(); }
bool isDefinedCosineOrSine(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; bool isDefinedCosineOrSineOrTangent(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
bool isBasedIntegerCappedBy(const char * integerString) const; bool isBasedIntegerCappedBy(const char * integerString) const;
bool isDivisionOfIntegers() const; bool isDivisionOfIntegers() const;
bool hasDefinedComplexApproximation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; bool hasDefinedComplexApproximation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;

View File

@@ -292,9 +292,9 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex
return !isMultivariablePolynomial; return !isMultivariablePolynomial;
} }
bool Expression::isDefinedCosineOrSine(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { bool Expression::isDefinedCosineOrSineOrTangent(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const {
ExpressionNode::Type t = type(); ExpressionNode::Type t = type();
if (t == ExpressionNode::Type::Cosine || t == ExpressionNode::Type::Sine) { if (t == ExpressionNode::Type::Cosine || t == ExpressionNode::Type::Sine || t == ExpressionNode::Type::Tangent) {
float r = childAtIndex(0).approximateToScalar<float>(context, complexFormat, angleUnit); float r = childAtIndex(0).approximateToScalar<float>(context, complexFormat, angleUnit);
if (!std::isnan(r)) { if (!std::isnan(r)) {
return true; return true;