1 #ifndef GENESIS_UTILS_COLOR_NORM_BOUNDARY_H_
2 #define GENESIS_UTILS_COLOR_NORM_BOUNDARY_H_
100 scale( min, max, intervals );
135 assert( boundaries_.size() >= 3 );
136 if( value < boundaries_.front() ) {
139 if( value > boundaries_.back() ) {
140 return boundaries_.size() - 1;
151 auto const it = std::upper_bound( boundaries_.begin(), boundaries_.end(), value );
152 assert(( it != boundaries_.end() ) xor ( value == boundaries_.back() ));
153 assert( it != boundaries_.begin() );
155 if( it == boundaries_.end() ) {
156 return boundaries_.size() - 2;
158 return std::distance( boundaries_.begin(), it ) - 1;
171 boundaries_ = values;
185 double const interv = ( max - min ) /
static_cast<double>( intervals );
186 for(
size_t i = 0; i < intervals; ++i ) {
187 boundaries_.push_back( min +
static_cast<double>(i) * interv );
189 boundaries_.push_back( max );
201 return autoscale( values.begin(), values.end(), intervals );
208 template <
class ForwardIterator>
210 ForwardIterator first, ForwardIterator last,
size_t intervals
213 auto min = std::numeric_limits<double>::max();
214 auto max = std::numeric_limits<double>::lowest();
217 while( first != last ) {
218 if( ! std::isfinite( *first ) || *first ==
mask_value() ) {
238 scale( min, max, intervals );
253 return boundaries_.size() >= 3 && std::is_sorted( boundaries_.begin(), boundaries_.end() );
261 if( boundaries_.size() < 3 ) {
262 throw std::runtime_error(
"Invalid Color Normalization with less than three boundaries." );
264 if( ! std::is_sorted( boundaries_.begin(), boundaries_.end() ) ) {
265 throw std::runtime_error(
"Invalid Color Normalization with unsorted boundaries." );
280 if( idx >=
static_cast<long>( boundaries_.size() - 1 )) {
287 assert( boundaries_.size() >= 3 );
288 return static_cast<double>( idx ) /
static_cast<double>( boundaries_.size() - 2 );
297 std::vector<double> boundaries_;
304 #endif // include guardmask_value_