WSL/SLF GitLab Repository

Commit ec3eb4a7 authored by Mathias Bavay's avatar Mathias Bavay
Browse files

A new gradient type has been added (blue-green isomorphic) and some small...

A new gradient type has been added (blue-green isomorphic) and some small things improved thanks to valgrind (one potential out of bounds read and with callgrind some small speed improvements)
parent e2e3db32
......@@ -155,7 +155,7 @@ const Array2D<double> legend::getLegend()
//values between 0 and 1
//see http://www.cs.rit.edu/~ncs/color/t_convert.html or https://secure.wikimedia.org/wikipedia/en/wiki/HSL_and_HSV#Conversion_from_HSL_to_RGB
void Color::RGBtoHSV(const double r, const double g, const double b,
void Color::RGBtoHSV(const double& r, const double& g, const double& b,
double &h, double &s, double &v)
{
const double minimum = min( min(r,g), b);
......@@ -184,7 +184,7 @@ void Color::RGBtoHSV(const double r, const double g, const double b,
h += 360;
}
void Color::HSVtoRGB(const double h, const double s, const double v, double &r, double &g, double &b)
void Color::HSVtoRGB(const double& h, const double& s, const double& v, double &r, double &g, double &b)
{
if( s==0 ) { //achromatic (grey)
r = g = b = v;
......@@ -242,6 +242,7 @@ void Gradient::set(const Type& type, const double& i_min, const double& i_max, c
else if(type==blue) model = new gr_blue(i_min, i_max, i_autoscale);
else if(type==blue_pink) model = new gr_blue_pink(i_min, i_max, i_autoscale);
else if(type==pastel) model = new gr_pastel(i_min, i_max, i_autoscale);
else if(type==bg_isomorphic) model = new gr_bg_isomorphic(i_min, i_max, i_autoscale);
}
//val between min_val and max_val
......@@ -266,7 +267,7 @@ void Gradient::getColor(const double& val, unsigned char& r, unsigned char& g, u
r=0; g=0; b=0; a=255;
return;
}
if(autoscale && delta_val==0) { //constant data through the grid & autoscale are no friends...
if(autoscale && delta_val==0) { //constant data throughout the grid & autoscale are no friends...
r=g=b=125; a=255;
return;
}
......@@ -285,21 +286,25 @@ void Gradient_model::setMinMax(const double& i_min, const double& i_max, const b
//we assume that the vectors are sorted by X
double Gradient_model::getInterpol(const double& val, const std::vector<double>& X, const std::vector<double>& Y) const
{
if(X.size()!=Y.size()) {
const size_t nr = X.size();
#ifndef NOSAFECHECKS
if(Y.size()!=nr) {
std::stringstream ss;
ss << "For color gradients interpolations, both X and Y vectors must have the same size! ";
ss << "There are " << X.size() << " abscissa for " << Y.size() << " ordinates.";
throw IOException(ss.str(), AT);
}
if(X.size()==0) {
if(nr==0) {
throw IOException("Empty vector of control points for color gradient interpolation", AT);
}
#endif
size_t i=0;
while(i<X.size() && X[i]<val) i++;
if(X[i]==val) return Y[i];
while(i<nr && X[i]<val) i++; //find index of first element greater than val
if(i==0) return Y[0];
if(i==Y.size()) return Y[ Y.size()-1 ];
if(i>=nr) return Y[ nr-1 ];
if(X[i]==val) return Y[i];
const double y = Y[i-1] + (val-X[i-1])/(X[i]-X[i-1]) * (Y[i]-Y[i-1]);
return y;
......@@ -398,6 +403,17 @@ gr_blue::gr_blue(const double& i_min, const double& i_max, const bool& i_autosca
for(size_t i=0; i<X.size(); i++) X[i] = X[i]*delta_val + min_val;
}
gr_bg_isomorphic::gr_bg_isomorphic(const double& i_min, const double& i_max, const bool& i_autoscale) {
setMinMax(i_min, i_max, i_autoscale);
//write gradient control points
X.push_back(0.); v_h.push_back(47.); v_s.push_back(.92); v_v.push_back(0.); //black
X.push_back(.5); v_h.push_back(178.); v_s.push_back(.58); v_v.push_back(.67); //light blue
X.push_back(1.); v_h.push_back(84.); v_s.push_back(.67); v_v.push_back(1.); //light green
for(size_t i=0; i<X.size(); i++) X[i] = X[i]*delta_val + min_val;
}
gr_pastel::gr_pastel(const double& i_min, const double& i_max, const bool& i_autoscale) {
setMinMax(i_min, i_max, i_autoscale);
......
......@@ -104,7 +104,7 @@ namespace Color {
* @param v value (between 0 and 1)
* @ingroup graphics
*/
void RGBtoHSV(const double r, const double g, const double b, double &h, double &s, double &v);
void RGBtoHSV(const double& r, const double& g, const double& b, double &h, double &s, double &v);
/**
* @brief convert HSV to RGB.
......@@ -119,7 +119,7 @@ namespace Color {
* @param b blue (between 0 and 1)
* @ingroup graphics
*/
void HSVtoRGB(const double h, const double s, const double v, double &r, double &g, double &b);
void HSVtoRGB(const double& h, const double& s, const double& v, double &r, double &g, double &b);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
......@@ -166,6 +166,9 @@ class Gradient_model {
* - setting min/max to fixed values (so the gradient will be rescaled between these fixed boundaries)
* - passing i_autoscale=false so the gradient might be able to set so fix points (like sea and snow line)
*
* For some interesting discussion on how to define color gradients, see Bernice E. Rogowitz, Lloyd A. Treinish
* "Why Should Engineers and Scientists Be Worried About Color?"
* http://www.research.ibm.com/people/l/lloydt/color/color.HTM
* @ingroup graphics
* @author Mathias Bavay
* @date 2012-01-06
......@@ -181,6 +184,7 @@ class Gradient {
freeze, ///< two, two-color gradients with a sharp transition at 0
blue_pink, ///< blue to pink gradient
pastel, ///< same color scale as "slope" but linear
bg_isomorphic, ///< drak-blue to light-green isomorphic gradient
blue ///< white to slightly violet gradient. This is similar to the one used for the SLF avalanche bulletin
} Type;
......@@ -256,6 +260,11 @@ class gr_blue : public Gradient_model {
gr_blue(const double& i_min, const double& i_max, const bool& i_autoscale);
};
class gr_bg_isomorphic : public Gradient_model {
public:
gr_bg_isomorphic(const double& i_min, const double& i_max, const bool& i_autoscale);
};
class gr_terrain : public Gradient_model {
public:
gr_terrain(const double& i_min, const double& i_max, const bool& i_autoscale);
......
......@@ -111,12 +111,12 @@ void ResamplingAlgorithms2D::Bilinear_nodata(Grid2DObject &o_grid, const Grid2DO
for (unsigned int jj=0; jj<o_grid.nrows; jj++) {
const double org_y = (double)jj/scale_y;
const unsigned int org_jj = (unsigned int) floor(org_y);
const unsigned int org_jj = static_cast<unsigned int>( org_y );
const double y = org_y - (double)org_jj; //normalized y, between 0 and 1
for (unsigned int ii=0; ii<o_grid.ncols; ii++) {
const double org_x = (double)ii/scale_x;
const unsigned int org_ii = (unsigned int) floor(org_x);
const unsigned int org_ii = static_cast<unsigned int>( org_x );
const double x = org_x - (double)org_ii; //normalized x, between 0 and 1
if(org_jj>=(org_nrows-1) || org_ii>=(org_ncols-1)) {
......@@ -148,15 +148,17 @@ void ResamplingAlgorithms2D::Bilinear_nodata(Grid2DObject &o_grid, const Grid2DO
avg_count++;
}
if(avg_count<=2) {
o_grid(ii,jj) = IOUtils::nodata;
continue;
}
if(avg_count==4) {
o_grid(ii,jj) = f_0_0 * (1.-x)*(1.-y) + f_1_0 * x*(1.-y) + f_0_1 * (1.-x)*y + f_1_1 *x*y;
continue;
}
//special cases: less than two neighbours or three neighbours
if(avg_count<=2) {
o_grid(ii,jj) = IOUtils::nodata;
continue;
}
double value = 0.;
const double avg = avg_value/(double)avg_count;
if(f_0_0!=IOUtils::nodata) value += f_0_0 * (1.-x)*(1.-y);
......
......@@ -429,7 +429,7 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameter
min -= Cst::t_water_freezing_pt;
max -= Cst::t_water_freezing_pt;
}
gradient.set(Gradient::freeze, min, max, autoscale);
gradient.set(Gradient::heat, min, max, autoscale);
} else if(parameter==MeteoGrids::TSS) {
grid.grid2D -= Cst::t_water_freezing_pt; //convert to celsius
if(!autoscale) {
......@@ -443,7 +443,12 @@ void PNGIO::write2DGrid(const Grid2DObject& grid_in, const MeteoGrids::Parameter
if(!autoscale) {
min = 0.; max = 1.;
}
gradient.set(Gradient::blue_pink, min, max, autoscale);
gradient.set(Gradient::bg_isomorphic, min, max, autoscale);
} else if(parameter==MeteoGrids::ALB) {
if(!autoscale) {
min = 0.; max = 1.;
}
gradient.set(Gradient::bg_isomorphic, min, max, autoscale);
} else if(parameter==MeteoGrids::SWE) {
if(!autoscale) {
min = 0.; max = 2000.;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment