mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare/zoom] Find range with specific ratio
Change-Id: Id0c816c42e3fa93519241bf53f920c333e204af1
This commit is contained in:
committed by
Émilie Feral
parent
08c96c5107
commit
403315f6ac
@@ -12,8 +12,11 @@ public:
|
||||
|
||||
typedef float (*ValueAtAbscissa)(float abscissa, Context * context, const void * auxiliary);
|
||||
|
||||
static void InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin, float * xMax, float * yMin, float * yMax, float tMin, float tMax, Context * context, const void * auxiliary);
|
||||
/* Return false if the X range was given a default value because there were
|
||||
* no points of interest. */
|
||||
static bool InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin, float * xMax, float * yMin, float * yMax, float tMin, float tMax, Context * context, const void * auxiliary);
|
||||
static void RefinedYRangeForDisplay(ValueAtAbscissa evaluation, float xMin, float xMax, float * yMin, float * yMax, Context * context, const void * auxiliary, bool boundByMagnitude = false);
|
||||
static void RangeWithRatioForDisplay(ValueAtAbscissa evaluation, float yxRatio, float * xMin, float * xMax, float * yMin, float * yMax, Context * context, const void * auxiliary);
|
||||
|
||||
/* If shrink is false, the range will be set to ratio by increasing the size
|
||||
* of the smallest axis. If it is true, the longest axis will be reduced.*/
|
||||
|
||||
@@ -17,7 +17,7 @@ constexpr float
|
||||
Zoom::k_defaultHalfRange,
|
||||
Zoom::k_maxRatioBetweenPointsOfInterest;
|
||||
|
||||
void Zoom::InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin, float * xMax, float * yMin, float * yMax, float tMin, float tMax, Context * context, const void * auxiliary) {
|
||||
bool Zoom::InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin, float * xMax, float * yMin, float * yMax, float tMin, float tMax, Context * context, const void * auxiliary) {
|
||||
assert(xMin && xMax && yMin && yMax);
|
||||
|
||||
const bool hasIntervalOfDefinition = std::isfinite(tMin) && std::isfinite(tMax);
|
||||
@@ -136,6 +136,7 @@ void Zoom::InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin,
|
||||
/* Fallback to default range. */
|
||||
resultX[0] = - k_defaultHalfRange;
|
||||
resultX[1] = k_defaultHalfRange;
|
||||
return false;
|
||||
} else {
|
||||
/* Add breathing room around points of interest. */
|
||||
float xRange = resultX[1] - resultX[0];
|
||||
@@ -147,6 +148,8 @@ void Zoom::InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin,
|
||||
|
||||
*yMin = std::min(resultYMin, *yMin);
|
||||
*yMax = std::max(resultYMax, *yMax);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Zoom::RefinedYRangeForDisplay(ValueAtAbscissa evaluation, float xMin, float xMax, float * yMin, float * yMax, Context * context, const void * auxiliary, bool boundByMagnitude) {
|
||||
@@ -222,6 +225,39 @@ void Zoom::SetToRatio(float yxRatio, float * xMin, float * xMax, float * yMin, f
|
||||
*tMin = center - newRange / 2.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 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 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;
|
||||
}
|
||||
|
||||
xRange *= step;
|
||||
}
|
||||
if (bestGrade == FLT_MAX) {
|
||||
*xMin = -k_defaultHalfRange;
|
||||
*xMax = k_defaultHalfRange;
|
||||
RefinedYRangeForDisplay(evaluation, *xMin, *xMax, yMin, yMax, context, auxiliary, true);
|
||||
return;
|
||||
}
|
||||
|
||||
SetToRatio(yxRatio, xMin, xMax, yMin, yMax, true);
|
||||
}
|
||||
|
||||
bool Zoom::IsConvexAroundExtremum(ValueAtAbscissa evaluation, float x1, float x2, float x3, float y1, float y2, float y3, Context * context, const void * auxiliary, int iterations) {
|
||||
if (iterations <= 0) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user