mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 07:00:17 -05:00
The lower limit of a logarithmic color range was computed from the value closest to zero, which is not always available. When this value was zero, log10() returned -inf and the lower limit ended up as zero. Use the closest power of ten below the lowest value instead, and use the value closest to zero only when the lowest value is zero or negative. Guard computeTenExponentCeil() and computeTenExponentFloor() against zero, and make sure the range always spans at least one decade.
123 lines
4.5 KiB
C++
123 lines
4.5 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2022 Equinor ASA
|
|
//
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
|
// for more details.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "RiaNumericalTools.h"
|
|
|
|
#include "cvfMath.h"
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RiaNumericalTools::roundToClosestPowerOfTenCeil( double value )
|
|
{
|
|
auto exponent = computeTenExponentCeil( value );
|
|
return pow( 10.0, exponent );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RiaNumericalTools::roundToClosestPowerOfTenFloor( double value )
|
|
{
|
|
auto exponent = computeTenExponentFloor( value );
|
|
return pow( 10.0, exponent );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RiaNumericalTools::computeTenExponentCeil( double value )
|
|
{
|
|
// log10() is not defined for zero and negative values
|
|
if ( value <= 0.0 ) return 0.0;
|
|
|
|
double logDecValueMax = log10( value );
|
|
logDecValueMax = cvf::Math::ceil( logDecValueMax );
|
|
|
|
return logDecValueMax;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RiaNumericalTools::computeTenExponentFloor( double value )
|
|
{
|
|
// log10() is not defined for zero and negative values
|
|
if ( value <= 0.0 ) return 0.0;
|
|
|
|
double logDecValueMin = log10( value );
|
|
logDecValueMin = cvf::Math::floor( logDecValueMin );
|
|
|
|
return logDecValueMin;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RiaNumericalTools::roundToNumSignificantDigitsFloor( double value, double numSignificantDigits )
|
|
{
|
|
return roundToNumSignificantDigits( value, numSignificantDigits, RoundToSignificantDigitsMode::FLOOR );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RiaNumericalTools::roundToNumSignificantDigitsCeil( double value, double numSignificantDigits )
|
|
{
|
|
return roundToNumSignificantDigits( value, numSignificantDigits, RoundToSignificantDigitsMode::CEIL );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
double RiaNumericalTools::roundToNumSignificantDigits( double value, double numSignificantDigits, RoundToSignificantDigitsMode mode )
|
|
{
|
|
double absoluteValue = cvf::Math::abs( value );
|
|
if ( absoluteValue == 0.0 )
|
|
{
|
|
return 0.0;
|
|
}
|
|
|
|
double logDecValue = log10( absoluteValue );
|
|
logDecValue = cvf::Math::ceil( logDecValue );
|
|
|
|
double factor = pow( 10.0, numSignificantDigits - logDecValue );
|
|
|
|
double tmp = value * factor;
|
|
double integerPart = 0.0;
|
|
modf( tmp, &integerPart );
|
|
|
|
double candidateValue = integerPart / factor;
|
|
|
|
if ( mode == RoundToSignificantDigitsMode::CEIL && candidateValue < value )
|
|
{
|
|
integerPart++;
|
|
}
|
|
else if ( mode == RoundToSignificantDigitsMode::FLOOR && value < candidateValue )
|
|
{
|
|
integerPart--;
|
|
}
|
|
|
|
double roundedValue = integerPart / factor;
|
|
|
|
return roundedValue;
|
|
}
|