[poincare/zoom] Change range forms for fixed ratio

When looking for a range with a certain ratio using
RangeWithRatioForDisplay, instead of looking for ranges of the form
0.01*1.1^n, search for ranges of the form a*10^k, with a being either 1,
  2, or 5.

Change-Id: I2eaa229574a9a6aa4afa6eb1a3d57365d3d52801
This commit is contained in:
Gabriel Ozouf
2020-10-12 11:41:37 +02:00
committed by Émilie Feral
parent 43f50b7b2d
commit 88ea32bd0d

View File

@@ -226,27 +226,29 @@ void Zoom::SetToRatio(float yxRatio, float * xMin, float * xMax, float * yMin, f
}
void Zoom::RangeWithRatioForDisplay(ValueAtAbscissa evaluation, float yxRatio, float * xMin, float * xMax, float * yMin, float * yMax, Context * context, const void * auxiliary) {
constexpr int searchSpeedUp = 13;
constexpr float units[] = {1.f, 2.f, 5.f};
constexpr float rangeMagnitudeWeight = 0.2f;
constexpr float maxMagnitudeDifference = 1.2f;
const float step = std::pow(k_stepFactor, searchSpeedUp);
float bestGrade = FLT_MAX;
float xRange = k_minimalDistance;
float xMagnitude = k_minimalDistance;
float yMinRange = FLT_MAX, yMaxRange = -FLT_MAX;
while (xRange < k_maximalDistance) {
RefinedYRangeForDisplay(evaluation, -xRange, xRange, &yMinRange, &yMaxRange, context, auxiliary, true);
float currentRatio = (yMaxRange - yMinRange) / (2 * xRange);
float grade = std::fabs(std::log(currentRatio / yxRatio)) + std::fabs(std::log(xRange / 10.f)) * rangeMagnitudeWeight;
if (std::fabs(std::log(currentRatio / yxRatio)) < maxMagnitudeDifference && grade < bestGrade) {
bestGrade = grade;
*xMin = -xRange;
*xMax = xRange;
*yMin = yMinRange;
*yMax = yMaxRange;
}
while (xMagnitude < k_maximalDistance) {
for(const float unit : units) {
const float xRange = unit * xMagnitude;
RefinedYRangeForDisplay(evaluation, -xRange, xRange, &yMinRange, &yMaxRange, context, auxiliary, true);
float currentRatio = (yMaxRange - yMinRange) / (2 * xRange);
float grade = std::fabs(std::log(currentRatio / yxRatio)) + std::fabs(std::log(xRange / 10.f)) * rangeMagnitudeWeight;
if (std::fabs(std::log(currentRatio / yxRatio)) < maxMagnitudeDifference && grade < bestGrade) {
bestGrade = grade;
*xMin = -xRange;
*xMax = xRange;
*yMin = yMinRange;
*yMax = yMaxRange;
}
xRange *= step;
}
xMagnitude *= 10.f;
}
if (bestGrade == FLT_MAX) {
*xMin = -k_defaultHalfRange;