mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 19:49:58 +02:00
Merge changes Ibd6dd8bf,I4d7229e3,Ie49a47f6,I7fd6a620,I7f88159d, ...
* changes: [apps/shared] In range, fix bug when clipping range values [apps/shared] In range parameter controller, fix bug [apps/shared] In interval, fix bug [apps/sequence] Fix bug: confusing rows and columns [poincare] Fix bug in store [poincare] In convert float to text, avoid getting infinite values by using log. [poincare] Fix bug in convert float to text
This commit is contained in:
@@ -18,7 +18,7 @@ public:
|
||||
bool textFieldDidFinishEditing(TextField * textField, const char * text) override;
|
||||
void viewWillAppear() override;
|
||||
private:
|
||||
constexpr static float k_maxDisplayableFloat = 1E7f;
|
||||
constexpr static float k_maxDisplayableFloat = 1E8f;
|
||||
HighlightCell * reusableParameterCell(int index, int type) override;
|
||||
int reusableParameterCellCount(int type) override;
|
||||
float previousParameterAtIndex(int index) override;
|
||||
|
||||
@@ -79,7 +79,7 @@ void ListController::willDisplayCellAtLocation(HighlightCell * cell, int i, int
|
||||
|
||||
void ListController::selectPreviousNewSequenceCell() {
|
||||
if (sequenceDefinitionForRow(m_selectableTableView.selectedRow()) >= 0) {
|
||||
m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedRow()-sequenceDefinitionForRow(m_selectableTableView.selectedRow()), m_selectableTableView.selectedColumn());
|
||||
m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()-sequenceDefinitionForRow(m_selectableTableView.selectedRow()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ public:
|
||||
float x();
|
||||
float y();
|
||||
void moveTo(float x, float y);
|
||||
static float clipped(float f);
|
||||
private:
|
||||
static float clipped(float f);
|
||||
constexpr static float k_maxFloat = 1E+8f;
|
||||
float m_x;
|
||||
float m_y;
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
void setFunction(Function * function);
|
||||
int numberOfRows() override;
|
||||
private:
|
||||
constexpr static float k_maxDisplayableFloat = 1E7f;
|
||||
constexpr static float k_maxDisplayableFloat = 1E8f;
|
||||
void buttonAction() override;
|
||||
HighlightCell * reusableParameterCell(int index, int type) override;
|
||||
int reusableParameterCellCount(int type) override;
|
||||
|
||||
@@ -34,10 +34,11 @@ bool InteractiveCurveViewRange::yAuto() {
|
||||
|
||||
void InteractiveCurveViewRange::setXMin(float xMin) {
|
||||
float newXMin = xMin;
|
||||
if (m_xMax - m_xMin < k_minFloat) {
|
||||
MemoizedCurveViewRange::setXMin(clipped(newXMin, false));
|
||||
if (m_xMax - newXMin < k_minFloat) {
|
||||
newXMin = m_xMax - k_minFloat;
|
||||
MemoizedCurveViewRange::setXMin(clipped(newXMin, false));
|
||||
}
|
||||
MemoizedCurveViewRange::setXMin(CurveViewCursor::clipped(newXMin));
|
||||
if (m_delegate) {
|
||||
m_delegate->didChangeRange(this);
|
||||
}
|
||||
@@ -45,10 +46,11 @@ void InteractiveCurveViewRange::setXMin(float xMin) {
|
||||
|
||||
void InteractiveCurveViewRange::setXMax(float xMax) {
|
||||
float newXMax = xMax;
|
||||
if (m_xMax - m_xMin < k_minFloat) {
|
||||
MemoizedCurveViewRange::setXMax(clipped(newXMax, true));
|
||||
if (newXMax - m_xMin < k_minFloat) {
|
||||
newXMax = m_xMin + k_minFloat;
|
||||
MemoizedCurveViewRange::setXMax(clipped(newXMax, true));
|
||||
}
|
||||
MemoizedCurveViewRange::setXMax(CurveViewCursor::clipped(newXMax));
|
||||
if (m_delegate) {
|
||||
m_delegate->didChangeRange(this);
|
||||
}
|
||||
@@ -56,18 +58,20 @@ void InteractiveCurveViewRange::setXMax(float xMax) {
|
||||
|
||||
void InteractiveCurveViewRange::setYMin(float yMin) {
|
||||
float newYMin = yMin;
|
||||
if (m_yMax - m_yMin < k_minFloat) {
|
||||
MemoizedCurveViewRange::setYMin(clipped(newYMin, false));
|
||||
if (m_yMax - newYMin < k_minFloat) {
|
||||
newYMin = m_yMax - k_minFloat;
|
||||
MemoizedCurveViewRange::setYMin(clipped(newYMin, false));
|
||||
}
|
||||
MemoizedCurveViewRange::setYMin(CurveViewCursor::clipped(newYMin));
|
||||
}
|
||||
|
||||
void InteractiveCurveViewRange::setYMax(float yMax) {
|
||||
float newYMax = yMax;
|
||||
if (m_yMax - m_yMin < k_minFloat) {
|
||||
MemoizedCurveViewRange::setYMax(clipped(newYMax, true));
|
||||
if (newYMax - m_yMin < k_minFloat) {
|
||||
newYMax = m_yMin + k_minFloat;
|
||||
MemoizedCurveViewRange::setYMax(clipped(newYMax, true));
|
||||
}
|
||||
MemoizedCurveViewRange::setYMax(CurveViewCursor::clipped(newYMax));
|
||||
}
|
||||
|
||||
void InteractiveCurveViewRange::setYAuto(bool yAuto) {
|
||||
@@ -85,24 +89,24 @@ void InteractiveCurveViewRange::zoom(float ratio) {
|
||||
if (2.0f*ratio*fabsf(xMax-xMin) < k_minFloat || 2.0f*ratio*fabsf(yMax-yMin) < k_minFloat) {
|
||||
return;
|
||||
}
|
||||
m_xMin = CurveViewCursor::clipped((xMax+xMin)/2.0f - ratio*fabsf(xMax-xMin));
|
||||
m_xMax = CurveViewCursor::clipped((xMax+xMin)/2.0f + ratio*fabsf(xMax-xMin));
|
||||
m_xMin = clipped((xMax+xMin)/2.0f - ratio*fabsf(xMax-xMin), false);
|
||||
m_xMax = clipped((xMax+xMin)/2.0f + ratio*fabsf(xMax-xMin), true);
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
m_yAuto = false;
|
||||
m_yMin = CurveViewCursor::clipped((yMax+yMin)/2.0f - ratio*fabsf(yMax-yMin));
|
||||
m_yMax = CurveViewCursor::clipped((yMax+yMin)/2.0f + ratio*fabsf(yMax-yMin));
|
||||
m_yMin = clipped((yMax+yMin)/2.0f - ratio*fabsf(yMax-yMin), false);
|
||||
m_yMax = clipped((yMax+yMin)/2.0f + ratio*fabsf(yMax-yMin), true);
|
||||
m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax);
|
||||
}
|
||||
|
||||
void InteractiveCurveViewRange::panWithVector(float x, float y) {
|
||||
m_yAuto = false;
|
||||
if (CurveViewCursor::clipped(m_xMin + x) != m_xMin + x || CurveViewCursor::clipped(m_xMax + x) != m_xMax + x || CurveViewCursor::clipped(m_yMin + y) != m_yMin + y || CurveViewCursor::clipped(m_yMax + y) != m_yMax + y) {
|
||||
if (clipped(m_xMin + x, false) != m_xMin + x || clipped(m_xMax + x, true) != m_xMax + x || clipped(m_yMin + y, false) != m_yMin + y || clipped(m_yMax + y, true) != m_yMax + y) {
|
||||
return;
|
||||
}
|
||||
m_xMin = CurveViewCursor::clipped(m_xMin + x);
|
||||
m_xMax = CurveViewCursor::clipped(m_xMax + x);
|
||||
m_yMin = CurveViewCursor::clipped(m_yMin + y);
|
||||
m_yMax = CurveViewCursor::clipped(m_yMax + y);
|
||||
m_xMin = clipped(m_xMin + x, false);
|
||||
m_xMax = clipped(m_xMax + x, true);
|
||||
m_yMin = clipped(m_yMin + y, false);
|
||||
m_yMax = clipped(m_yMax + y, true);
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax);
|
||||
}
|
||||
@@ -110,8 +114,8 @@ void InteractiveCurveViewRange::panWithVector(float x, float y) {
|
||||
void InteractiveCurveViewRange::roundAbscissa() {
|
||||
float xMin = m_xMin;
|
||||
float xMax = m_xMax;
|
||||
m_xMin = roundf((xMin+xMax)/2) - (float)Ion::Display::Width/2.0f;
|
||||
m_xMax = roundf((xMin+xMax)/2) + (float)Ion::Display::Width/2.0f-1.0f;
|
||||
m_xMin = clipped(roundf((xMin+xMax)/2) - (float)Ion::Display::Width/2.0f, false);
|
||||
m_xMax = clipped(roundf((xMin+xMax)/2) + (float)Ion::Display::Width/2.0f-1.0f, true);
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
if (m_delegate) {
|
||||
m_delegate->didChangeRange(this);
|
||||
@@ -123,12 +127,12 @@ void InteractiveCurveViewRange::normalize() {
|
||||
float xMax = m_xMax;
|
||||
float yMin = m_yMin;
|
||||
float yMax = m_yMax;
|
||||
m_xMin = (xMin+xMax)/2 - 5.3f;
|
||||
m_xMax = (xMin+xMax)/2 + 5.3f;
|
||||
m_xMin = clipped((xMin+xMax)/2 - 5.3f, false);
|
||||
m_xMax = clipped((xMin+xMax)/2 + 5.3f, true);
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
m_yAuto = false;
|
||||
m_yMin = (yMin+yMax)/2 - 3.1f;
|
||||
m_yMax = (yMin+yMax)/2 + 3.1f;
|
||||
m_yMin = clipped((yMin+yMax)/2 - 3.1f, false);
|
||||
m_yMax = clipped((yMin+yMax)/2 + 3.1f, true);
|
||||
m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax);
|
||||
}
|
||||
|
||||
@@ -156,15 +160,15 @@ void InteractiveCurveViewRange::setDefault() {
|
||||
void InteractiveCurveViewRange::centerAxisAround(Axis axis, float position) {
|
||||
if (axis == Axis::X) {
|
||||
float range = m_xMax - m_xMin;
|
||||
m_xMin = CurveViewCursor::clipped(position - range/2.0f);
|
||||
m_xMax = CurveViewCursor::clipped(position + range/2.0f);
|
||||
m_xMin = clipped(position - range/2.0f, false);
|
||||
m_xMax = clipped(position + range/2.0f, true);
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
} else {
|
||||
m_yAuto = false;
|
||||
float range = m_yMax - m_yMin;
|
||||
m_yMin = CurveViewCursor::clipped(position - range/2.0f);
|
||||
m_yMax = CurveViewCursor::clipped(position + range/2.0f);
|
||||
m_yGridUnit = CurveViewCursor::clipped(computeGridUnit(Axis::Y, m_yMin, m_yMax));
|
||||
m_yMin = clipped(position - range/2.0f, false);
|
||||
m_yMax = clipped(position + range/2.0f, true);
|
||||
m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,29 +176,37 @@ void InteractiveCurveViewRange::panToMakePointVisible(float x, float y, float to
|
||||
float xRange = m_xMax - m_xMin;
|
||||
float yRange = m_yMax - m_yMin;
|
||||
if (x < m_xMin + leftMarginRation*xRange && !isinf(x) && !isnan(x)) {
|
||||
m_xMin = CurveViewCursor::clipped(x - leftMarginRation*xRange);
|
||||
m_xMax = m_xMin + xRange;
|
||||
m_xMin = clipped(x - leftMarginRation*xRange, false);
|
||||
m_xMax = clipped(m_xMin + xRange, true);
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
m_yAuto = false;
|
||||
}
|
||||
if (x > m_xMax - rightMarginRatio*xRange && !isinf(x) && !isnan(x)) {
|
||||
m_xMax = CurveViewCursor::clipped(x + rightMarginRatio*xRange);
|
||||
m_xMin = m_xMax - xRange;
|
||||
m_xMax = clipped(x + rightMarginRatio*xRange, true);
|
||||
m_xMin = clipped(m_xMax - xRange, false);
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
m_yAuto = false;
|
||||
}
|
||||
if (y < m_yMin + bottomMarginRation*yRange && !isinf(y) && !isnan(y)) {
|
||||
m_yMin = CurveViewCursor::clipped(y - bottomMarginRation*yRange);
|
||||
m_yMax = m_yMin + yRange;
|
||||
m_yMin = clipped(y - bottomMarginRation*yRange, false);
|
||||
m_yMax = clipped(m_yMin + yRange, true);
|
||||
m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax);
|
||||
m_yAuto = false;
|
||||
}
|
||||
if (y > m_yMax - topMarginRatio*yRange && !isinf(y) && !isnan(y)) {
|
||||
m_yMax = CurveViewCursor::clipped(y + topMarginRatio*yRange);
|
||||
m_yMin = m_yMax - yRange;
|
||||
m_yMax = clipped(y + topMarginRatio*yRange, true);
|
||||
m_yMin = clipped(m_yMax - yRange, false);
|
||||
m_yGridUnit = computeGridUnit(Axis::Y, m_yMin, m_yMax);
|
||||
m_yAuto = false;
|
||||
}
|
||||
}
|
||||
|
||||
float InteractiveCurveViewRange::clipped(float x, bool isMax) {
|
||||
float max = isMax ? k_upperMaxFloat : k_lowerMaxFloat;
|
||||
float min = isMax ? -k_lowerMaxFloat : -k_upperMaxFloat;
|
||||
float clippedX = x > max ? max : x;
|
||||
clippedX = clippedX < min ? min : clippedX;
|
||||
return clippedX;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ protected:
|
||||
InteractiveCurveViewRangeDelegate * m_delegate;
|
||||
private:
|
||||
constexpr static float k_minFloat = 1E-8f;
|
||||
constexpr static float k_upperMaxFloat = 1E+8f;
|
||||
constexpr static float k_lowerMaxFloat = 9E+7f;
|
||||
static float clipped(float f, bool isMax);
|
||||
CurveViewCursor * m_cursor;
|
||||
};
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ void Interval::computeElements() {
|
||||
m_numberOfElements = 0;
|
||||
} else {
|
||||
m_numberOfElements = m_step > 0 ? 1 + (m_end - m_start)/m_step : k_maxNumberOfElements;
|
||||
m_numberOfElements = m_numberOfElements > k_maxNumberOfElements ? k_maxNumberOfElements : m_numberOfElements;
|
||||
m_numberOfElements = m_numberOfElements > k_maxNumberOfElements || m_numberOfElements < 0 ? k_maxNumberOfElements : m_numberOfElements;
|
||||
}
|
||||
for (int i = 0; i < m_numberOfElements; i += 1) {
|
||||
m_intervalBuffer[i] = m_start + i * m_step;
|
||||
|
||||
@@ -42,7 +42,7 @@ float MemoizedCurveViewRange::yGridUnit() {
|
||||
void MemoizedCurveViewRange::setXMin(float xMin) {
|
||||
m_xMin = xMin;
|
||||
if (m_xMin >= m_xMax) {
|
||||
m_xMax = xMin + 1.0f;
|
||||
m_xMax = xMin + powf(10.0f, floorf(log10f(fabsf(xMin)))-1.0f);
|
||||
}
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
}
|
||||
@@ -50,7 +50,7 @@ void MemoizedCurveViewRange::setXMin(float xMin) {
|
||||
void MemoizedCurveViewRange::setXMax(float xMax) {
|
||||
m_xMax = xMax;
|
||||
if (m_xMin >= m_xMax) {
|
||||
m_xMin = xMax - 1.0f;
|
||||
m_xMin = xMax - powf(10.0f, floorf(log10f(fabsf(xMax)))-1.0f);
|
||||
}
|
||||
m_xGridUnit = computeGridUnit(Axis::X, m_xMin, m_xMax);
|
||||
}
|
||||
|
||||
@@ -91,16 +91,10 @@ void RangeParameterController::tableViewDidChangeSelection(SelectableTableView *
|
||||
}
|
||||
|
||||
bool RangeParameterController::handleEvent(Ion::Events::Event event) {
|
||||
if (activeCell() == 2) {
|
||||
if (event == Ion::Events::OK) {
|
||||
m_interactiveRange->setYAuto(!m_interactiveRange->yAuto());
|
||||
m_selectableTableView.reloadData();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (m_interactiveRange->yAuto() && (activeCell() == 3 || activeCell() == 4)) {
|
||||
return false;
|
||||
if (activeCell() == 2 && event == Ion::Events::OK) {
|
||||
m_interactiveRange->setYAuto(!m_interactiveRange->yAuto());
|
||||
m_selectableTableView.reloadData();
|
||||
return true;
|
||||
}
|
||||
if (event == Ion::Events::Back) {
|
||||
m_interactiveRange->setYAuto(m_previousSwitchState);
|
||||
|
||||
@@ -252,11 +252,10 @@ int Complex::convertFloatToTextPrivate(float f, char * buffer, int numberOfSigni
|
||||
}
|
||||
|
||||
float logBase10 = f != 0.0f ? log10f(fabsf(f)) : 0;
|
||||
int exponentInBase10 = logBase10;
|
||||
if ((int)f == 0 && logBase10 != exponentInBase10) {
|
||||
/* For floats < 0, the exponent in base 10 is the inferior integer part of
|
||||
* log10(float). We thus decrement the exponent for float < 0 whose exponent
|
||||
* is not an integer. */
|
||||
int exponentInBase10 = floorf(logBase10);
|
||||
/* Correct the exponent in base 10: sometines the exact log10 of f is 6.999999
|
||||
* but is stored as 7 in hardware. We catch these cases here. */
|
||||
if (f != 0.0f && logBase10 == (int)logBase10 && fabsf(f) < powf(10.0f, logBase10)) {
|
||||
exponentInBase10--;
|
||||
}
|
||||
|
||||
@@ -280,12 +279,30 @@ int Complex::convertFloatToTextPrivate(float f, char * buffer, int numberOfSigni
|
||||
assert(availableCharsForMantissaWithoutSign - 1 < numberMaximalOfCharsInInteger);
|
||||
int numberOfDigitBeforeDecimal = exponentInBase10 >= 0 || displayMode == FloatDisplayMode::Scientific ?
|
||||
exponentInBase10 + 1 : 1;
|
||||
int mantissa = roundf(f * powf(10, availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal));
|
||||
float mantissa = roundf(f * powf(10.0f, availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal));
|
||||
/* if availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal
|
||||
* is too big (or too small), mantissa is now inf. We handle this case by
|
||||
* using logarithm function. */
|
||||
if (isnan(mantissa) || isinf(mantissa)) {
|
||||
mantissa = roundf(powf(10.0f, log10f(f)+(float)(availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal)));
|
||||
}
|
||||
/* We update the exponent in base 10 (if 0.99999999 was rounded to 1 for
|
||||
* instance) */
|
||||
float truncatedMantissa = (int)(f * powf(10, availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal));
|
||||
if (isinf(truncatedMantissa) || isnan(truncatedMantissa)) {
|
||||
truncatedMantissa = (int)(powf(10.0f, log10f(f)+(float)(availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal)));
|
||||
}
|
||||
if (mantissa != truncatedMantissa) {
|
||||
float newLogBase10 = mantissa != 0.0f ? log10f(fabsf(mantissa/powf(10, availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal))) : 0.0f;
|
||||
if (isnan(newLogBase10) || isinf(newLogBase10)) {
|
||||
newLogBase10 = log10f(fabsf(mantissa)) - (float)(availableCharsForMantissaWithoutSign - 1 - numberOfDigitBeforeDecimal);
|
||||
}
|
||||
exponentInBase10 = floorf(newLogBase10);
|
||||
}
|
||||
// Correct the number of digits in mantissa after rounding
|
||||
int mantissaExponentInBase10 = exponentInBase10 > 0 || displayMode == FloatDisplayMode::Scientific ? availableCharsForMantissaWithoutSign - 1 : availableCharsForMantissaWithoutSign + exponentInBase10;
|
||||
if ((int)(mantissa * powf(10, - mantissaExponentInBase10)) > 0) {
|
||||
mantissa = mantissa/10;
|
||||
exponentInBase10++;
|
||||
}
|
||||
|
||||
int numberOfCharExponent = exponentInBase10 != 0 ? log10f(fabsf((float)exponentInBase10)) + 1 : 1;
|
||||
|
||||
@@ -76,7 +76,10 @@ Expression * Store::privateEvaluate(Context& context, AngleUnit angleUnit) const
|
||||
Expression * valueEvaluation = m_value->evaluate(context, angleUnit);
|
||||
context.setExpressionForSymbolName(valueEvaluation, m_symbol);
|
||||
delete valueEvaluation;
|
||||
return context.expressionForSymbol(m_symbol)->clone();
|
||||
if (context.expressionForSymbol(m_symbol) != nullptr) {
|
||||
return context.expressionForSymbol(m_symbol)->clone();
|
||||
}
|
||||
return new Complex(Complex::Float(NAN));
|
||||
}
|
||||
|
||||
float Store::privateApproximate(Context& context, AngleUnit angleUnit) const {
|
||||
|
||||
Reference in New Issue
Block a user