mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
Merge pull request #254 from RedGl0w/additional_result_trigo
Changes to the trigonometry additional result
This commit is contained in:
@@ -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<float>(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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -251,8 +251,11 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co
|
||||
* - > input: 2cos(2) - cos(2)
|
||||
* > output: cos(2)
|
||||
*/
|
||||
if (input().isDefinedCosineOrSine(context, complexFormat, preferences->angleUnit()) || o.isDefinedCosineOrSine(context, complexFormat, preferences->angleUnit())) {
|
||||
return AdditionalInformationType::Trigonometry;
|
||||
if (i.isDefinedCosineOrSineOrTangent(context, complexFormat, preferences->angleUnit())) {
|
||||
return AdditionalInformationType::TrigonometryInput;
|
||||
}
|
||||
if (o.isDefinedCosineOrSineOrTangent(context, complexFormat, preferences->angleUnit())) {
|
||||
return AdditionalInformationType::TrigonometryOutput;
|
||||
}
|
||||
if (o.hasUnit()) {
|
||||
Expression unit;
|
||||
|
||||
@@ -40,7 +40,8 @@ public:
|
||||
Integer,
|
||||
Rational,
|
||||
SecondDegree,
|
||||
Trigonometry,
|
||||
TrigonometryInput,
|
||||
TrigonometryOutput,
|
||||
Unit,
|
||||
Matrix,
|
||||
Complex
|
||||
|
||||
@@ -103,12 +103,12 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
|
||||
vc = &m_complexController;
|
||||
} else if (additionalInfoType == Calculation::AdditionalInformationType::SecondDegree) {
|
||||
vc = &m_secondDegreeController;
|
||||
} else if (additionalInfoType == Calculation::AdditionalInformationType::Trigonometry) {
|
||||
} else if (additionalInfoType == Calculation::AdditionalInformationType::TrigonometryInput) {
|
||||
vc = &m_trigonometryController;
|
||||
// Find which of the input or output is the cosine/sine
|
||||
ExpressionNode::Type t = e.type();
|
||||
e = t == ExpressionNode::Type::Cosine || t == ExpressionNode::Type::Sine ? e : calculationAtIndex(focusRow)->input();
|
||||
} else if (additionalInfoType == Calculation::AdditionalInformationType::Integer) {
|
||||
e = calculationAtIndex(focusRow)->input();
|
||||
} else if (additionalInfoType == Calculation::AdditionalInformationType::TrigonometryOutput) {
|
||||
vc = &m_trigonometryController;
|
||||
} else if (additionalInfoType == Calculation::AdditionalInformationType::Integer) {
|
||||
vc = &m_integerController;
|
||||
} else if (additionalInfoType == Calculation::AdditionalInformationType::Rational) {
|
||||
vc = &m_rationalController;
|
||||
|
||||
@@ -183,7 +183,7 @@ public:
|
||||
bool isRationalOne() const;
|
||||
bool isRandom() const { return node()->isRandom(); }
|
||||
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 isDivisionOfIntegers() const;
|
||||
bool hasDefinedComplexApproximation(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const;
|
||||
|
||||
@@ -292,9 +292,9 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex
|
||||
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();
|
||||
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);
|
||||
if (!std::isnan(r)) {
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user