[graph] Take margins into account for normalization

When building an orthonormal range for the automatic zoom, we provide a
ratio for the screen without the margins. This way, adding the margins
will make the graph orthonormal, and the banner cannot cover the
function.

Change-Id: If3a3f799d4e7e3e81ab77c6b418d70b734a6fbca
This commit is contained in:
Gabriel Ozouf
2020-11-17 12:18:38 +01:00
committed by LeaNumworks
parent a8858023ba
commit c89a7bc496
7 changed files with 10 additions and 9 deletions

View File

@@ -261,7 +261,7 @@ void ContinuousFunction::setTMax(float tMax) {
setCache(nullptr);
}
void ContinuousFunction::rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, Poincare::Context * context) const {
void ContinuousFunction::rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, float targetRatio, Poincare::Context * context) const {
if (plotType() != PlotType::Cartesian) {
assert(std::isfinite(tMin()) && std::isfinite(tMax()) && std::isfinite(rangeStep()) && rangeStep() > 0);
protectedFullRangeForDisplay(tMin(), tMax(), rangeStep(), xMin, xMax, context, true);
@@ -291,7 +291,7 @@ void ContinuousFunction::rangeForDisplay(float * xMin, float * xMax, float * yMi
}
/* Try to display an orthonormal range. */
Zoom::RangeWithRatioForDisplay(evaluation, InteractiveCurveViewRange::NormalYXRatio(), xMin, xMax, yMin, yMax, context, this);
Zoom::RangeWithRatioForDisplay(evaluation, targetRatio, xMin, xMax, yMin, yMax, context, this);
if (std::isfinite(*xMin) && std::isfinite(*xMax) && std::isfinite(*yMin) && std::isfinite(*yMax)) {
return;
}

View File

@@ -70,7 +70,7 @@ public:
void setTMax(float tMax);
float rangeStep() const override { return plotType() == PlotType::Cartesian ? NAN : (tMax() - tMin())/k_polarParamRangeSearchNumberOfPoints; }
void rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, Poincare::Context * context) const override;
void rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, float targetRatio, Poincare::Context * context) const override;
// Extremum
Poincare::Coordinate2D<double> nextMinimumFrom(double start, double step, double max, Poincare::Context * context) const;

View File

@@ -55,7 +55,7 @@ public:
virtual Poincare::Expression sumBetweenBounds(double start, double end, Poincare::Context * context) const = 0;
// Range
virtual void rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, Poincare::Context * context) const = 0;
virtual void rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, float targetRatio, Poincare::Context * context) const = 0;
protected:
/* RecordDataBuffer is the layout of the data buffer of Record

View File

@@ -159,9 +159,11 @@ void FunctionGraphController::interestingRanges(InteractiveCurveViewRange * rang
float xMins[maxLength], xMaxs[maxLength], yMins[maxLength], yMaxs[maxLength];
int length = functionStore()->numberOfActiveFunctions();
float ratio = InteractiveCurveViewRange::NormalYXRatio() / (1 + cursorTopMarginRatio() + cursorBottomMarginRatio());
for (int i = 0; i < length; i++) {
ExpiringPointer<Function> f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));
f->rangeForDisplay(xMins + i, xMaxs + i, yMins + i, yMaxs + i, context);
f->rangeForDisplay(xMins + i, xMaxs + i, yMins + i, yMaxs + i, ratio, context);
}
float xMin, xMax, yMin, yMax;

View File

@@ -181,7 +181,6 @@ void InteractiveCurveViewRange::setDefault() {
// Compute the interesting range
m_delegate->interestingRanges(this);
bool revertToNormalized = isOrthonormal(k_orthonormalTolerance);
/* If the horizontal bounds are integers, they are preset values and should
* not be changed. */
bool isDefaultRange = (xMin() == std::round(xMin())) && (xMax() == std::round(xMax()));
@@ -200,7 +199,7 @@ void InteractiveCurveViewRange::setDefault() {
m_yRange.setMin(roundLimit(m_delegate->addMargin(yMin(), yRange, true , true), yRange, true), k_lowerMaxFloat, k_upperMaxFloat);
MemoizedCurveViewRange::protectedSetYMax(roundLimit(m_delegate->addMargin(yMax(), yRange, true , false), yRange, false), k_lowerMaxFloat, k_upperMaxFloat);
if (m_delegate->defaultRangeIsNormalized() || revertToNormalized) {
if (m_delegate->defaultRangeIsNormalized() || isOrthonormal(k_orthonormalTolerance)) {
/* Normalize the axes, so that a polar circle is displayed as a circle.
* If we are displaying cartesian functions with a default range, we want
* the X bounds untouched. */

View File

@@ -302,7 +302,7 @@ Expression Sequence::sumBetweenBounds(double start, double end, Poincare::Contex
return Float<double>::Builder(result);
}
void Sequence::rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, Poincare::Context * context) const {
void Sequence::rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, float targetRatio, Poincare::Context * context) const {
Poincare::Zoom::ValueAtAbscissa evaluation = [](float x, Poincare::Context * context, const void * auxiliary) {
return static_cast<float>(static_cast<const Shared::Sequence *>(auxiliary)->initialRank());
};

View File

@@ -75,7 +75,7 @@ public:
constexpr static int k_initialRankNumberOfDigits = 3; // m_initialRank is capped by 999
//Range
void rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, Poincare::Context * context) const override;
void rangeForDisplay(float * xMin, float * xMax, float * yMin, float * yMax, float targetRatio, Poincare::Context * context) const override;
private:
constexpr static const KDFont * k_layoutFont = KDFont::LargeFont;