mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[poincare/zoom] Handle undefined functions
Rework the logic so that :
- an undefined function will be displayed with a clealry defined
null range.
- display both an undefined function and a correct function at the
same time will not affect the correct range.
Change-Id: Ife9dc0d2ace667cab5a6b8826347078fca33e4d5
This commit is contained in:
committed by
Émilie Feral
parent
20cbefad41
commit
958b172d08
@@ -285,10 +285,39 @@ void ContinuousFunction::rangeForDisplay(float * xMin, float * xMax, float * yMi
|
||||
};
|
||||
|
||||
if (fullyComputed) {
|
||||
/* The function has points of interest. */
|
||||
Zoom::RefinedYRangeForDisplay(evaluation, *xMin, *xMax, yMin, yMax, context, this);
|
||||
} else {
|
||||
Zoom::RangeWithRatioForDisplay(evaluation, InteractiveCurveViewRange::NormalYXRatio(), xMin, xMax, yMin, yMax, context, this);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Try to display an orthonormal range. */
|
||||
Zoom::RangeWithRatioForDisplay(evaluation, InteractiveCurveViewRange::NormalYXRatio(), xMin, xMax, yMin, yMax, context, this);
|
||||
if (std::isfinite(*xMin) && std::isfinite(*xMax) && std::isfinite(*yMin) && std::isfinite(*yMax)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The function's profile is not great for an orthonormal range.
|
||||
* Try a basic range. */
|
||||
*xMin = - Zoom::k_defaultHalfRange;
|
||||
*xMax = Zoom::k_defaultHalfRange;
|
||||
Zoom::RefinedYRangeForDisplay(evaluation, *xMin, *xMax, yMin, yMax, context, this);
|
||||
if (std::isfinite(*xMin) && std::isfinite(*xMax) && std::isfinite(*yMin) && std::isfinite(*yMax)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The function's order of magnitude cannot be computed. Try to just display
|
||||
* the full function. */
|
||||
float step = (*xMax - *xMin) / k_polarParamRangeSearchNumberOfPoints;
|
||||
Zoom::FullRange(evaluation, *xMin, *xMax, step, yMin, yMax, context, this);
|
||||
if (std::isfinite(*xMin) && std::isfinite(*xMax) && std::isfinite(*yMin) && std::isfinite(*yMax)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The function is probably undefined. */
|
||||
*xMin = NAN;
|
||||
*xMax = NAN;
|
||||
*yMin = NAN;
|
||||
*yMax = NAN;
|
||||
}
|
||||
|
||||
void * ContinuousFunction::Model::expressionAddress(const Ion::Storage::Record * record) const {
|
||||
|
||||
@@ -160,12 +160,15 @@ void FunctionGraphController::interestingRanges(InteractiveCurveViewRange * rang
|
||||
float xMin, xMax, yMin, yMax;
|
||||
Poincare::Zoom::CombineRanges(length, xMins, xMaxs, &xMin, &xMax);
|
||||
Poincare::Zoom::CombineRanges(length, yMins, yMaxs, &yMin, &yMax);
|
||||
range->setXMin(xMin);
|
||||
range->setXMax(xMax);
|
||||
range->setYMin(yMin);
|
||||
range->setYMax(yMax);
|
||||
|
||||
yRangeForCursorFirstMove(range);
|
||||
if (std::isfinite(xMin) && std::isfinite(xMax) && std::isfinite(yMin) && std::isfinite(yMax) && xMax > xMin && yMax > yMin) {
|
||||
range->setXMin(xMin);
|
||||
range->setXMax(xMax);
|
||||
range->setYMin(yMin);
|
||||
range->setYMax(yMax);
|
||||
yRangeForCursorFirstMove(range);
|
||||
} else {
|
||||
range->setNullRange();
|
||||
}
|
||||
}
|
||||
|
||||
void FunctionGraphController::yRangeForCursorFirstMove(InteractiveCurveViewRange * range) const {
|
||||
|
||||
@@ -134,6 +134,14 @@ void InteractiveCurveViewRange::setDefault() {
|
||||
normalize();
|
||||
}
|
||||
|
||||
void InteractiveCurveViewRange::setNullRange() {
|
||||
m_xRange.setMin(- Range1D::k_default);
|
||||
setXMax(Range1D::k_default);
|
||||
m_yRange.setMin(0);
|
||||
m_yRange.setMax(0);
|
||||
normalize();
|
||||
}
|
||||
|
||||
void InteractiveCurveViewRange::centerAxisAround(Axis axis, float position) {
|
||||
if (std::isnan(position)) {
|
||||
return;
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
void panWithVector(float x, float y);
|
||||
virtual void normalize();
|
||||
virtual void setDefault();
|
||||
void setNullRange();
|
||||
void centerAxisAround(Axis axis, float position);
|
||||
void panToMakePointVisible(float x, float y, float topMarginRatio, float rightMarginRatio, float bottomMarginRation, float leftMarginRation, float pixelWidth);
|
||||
void checkForNormalizedRange();
|
||||
|
||||
@@ -146,8 +146,8 @@ bool Zoom::InterestingRangesForDisplay(ValueAtAbscissa evaluation, float * xMin,
|
||||
resultX[1] = std::max(resultX[1], asymptote[1]);
|
||||
if (resultX[0] >= resultX[1]) {
|
||||
/* Fallback to default range. */
|
||||
resultX[0] = - k_defaultHalfRange;
|
||||
resultX[1] = k_defaultHalfRange;
|
||||
resultX[0] = NAN;
|
||||
resultX[1] = NAN;
|
||||
return false;
|
||||
} else {
|
||||
resultX[0] = std::min(resultX[0], explosion[0]);
|
||||
@@ -195,8 +195,9 @@ void Zoom::RefinedYRangeForDisplay(ValueAtAbscissa evaluation, float xMin, float
|
||||
* order of magnitude and is used to cut the Y range. */
|
||||
|
||||
if (pop == 0) {
|
||||
*yMin = 0;
|
||||
*yMax = 0;
|
||||
*yMin = NAN;
|
||||
*yMax = NAN;
|
||||
return;
|
||||
} else {
|
||||
float bound = std::exp(sum / pop + 1.f);
|
||||
sampleYMin = std::max(sampleYMin, - bound);
|
||||
@@ -286,9 +287,10 @@ void Zoom::RangeWithRatioForDisplay(ValueAtAbscissa evaluation, float yxRatio, f
|
||||
xMagnitude *= 10.f;
|
||||
}
|
||||
if (bestGrade == FLT_MAX) {
|
||||
*xMin = -k_defaultHalfRange;
|
||||
*xMax = k_defaultHalfRange;
|
||||
RefinedYRangeForDisplay(evaluation, *xMin, *xMax, yMin, yMax, context, auxiliary);
|
||||
*xMin = NAN;
|
||||
*xMax = NAN;
|
||||
*yMin = NAN;
|
||||
*yMax = NAN;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -309,6 +311,10 @@ void Zoom::FullRange(ValueAtAbscissa evaluation, float tMin, float tMax, float t
|
||||
}
|
||||
t += tStep;
|
||||
}
|
||||
if (*fMin > *fMax) {
|
||||
*fMin = NAN;
|
||||
*fMax = NAN;
|
||||
}
|
||||
}
|
||||
|
||||
void Zoom::RangeFromSingleValue(float value, float * boundMin, float * boundMax) {
|
||||
|
||||
Reference in New Issue
Block a user