[GRASS-dev] G_exp_colors()?

Glynn Clements glynn at gclements.plus.com
Tue Apr 8 22:41:23 EDT 2008


Hamish wrote:

> > > the problem is the data is 90% done by 0.4, but the colr/ rules
> > > are only written out on integer values
> 
> Glynn:
> > Ah. Does the attached patch fix the problem?
> 
> 
> yes, it does. thanks.
> 
> 
> There are still slight differences (white spots),
> 
> G63> r.info -r A20023352002365.L3m_MO_CHLO_4.chlor_A
> min=0.010000
> max=64.565418
> 
> G63> r.colors A20023352002365.L3m_MO_CHLO_4.chlor_A col=bcyr -g
> G63> cat colr/A20023352002365.L3m_MO_CHLO_4.chlor_A
> % 0.010000000000000003677613769071 64.565417527653337970150460023433
> nv:255
> *:255
> 0.010000000000000003677613769071:0:0:255 0.0109169168:0:7:255
> 0.0109169168:0:7:255 0.0119179072:0:15:255
> 0.0119179072:0:15:255 0.0130106801:0:22:255
> 0.0130106801:0:22:255 0.0142036512:0:30:255
> 0.0142036512:0:30:255 0.0155060078:0:38:255
> 0.0155060078:0:38:255 0.0169277797:0:45:255
> 0.0169277797:0:45:255 0.0184799162:0:53:255
> ....
> 49.6249366001:255:23:0 54.1751303026:255:16:0
> 54.1751303026:255:16:0 59.1425389006:255:8:0
> 59.1425389006:255:8:0 64.565417527653337970150460023433:255:0:0
> 
> 
> the lowest values are less than the first color rule so they display as
> white. As do the max cell values which are slightly bigger than the color
> rule number with excessive number of decimal digits.

Bear in mind that "r.info -r" is approximating the min/max values to 6
decimal places. The actual min/max will be much closer to the values
in the first line of the colr file. IEEE "double" is ~15 significant
decimal digits.

> replace r.colors/rules.c "%.25f" with %.15g or %.16g ?
>  http://article.gmane.org/gmane.comp.gis.grass.devel/25291

That won't help at all. Excess digits in the decimal representation
won't do any harm; excess precision just gets discarded when the file
is read in.

Given that this seems to be specific to the use of G_log_colors(), I
suspect that the problem is due to slight errors in the calculation:

	lx = lmin + (lmax - lmin) * i / samples;
	x = exp(lx);

Theoretically:

i == 0:

	lx = lmin + (lmax - lmin) * 0 / samples
	   = lmin + (lmax - lmin) * 0
	   = lmin
	x = exp(lx)
	  = exp(lmin)
	  = min

i == samples:

	lx = lmin + (lmax - lmin) * samples / samples;
	   = lmin + (lmax - lmin) * 1;
	   = lmin + lmax - lmin;
	   = lmax
	x = exp(lx)
	  = exp(lmax)
	  = max

However, real arithmetic and floating-point arithmetic aren't quite
the same thing, and even the slightest error will cause the tests in
the lookup code to fail.

I can modify G_log_colors() to use special cases for i==0 and
i==samples (see attached patch).

Another option would be to add an extra rule at each end, so that any
values which are slightly out of range (by how much?) just use the end
colours.

But I'm wondering if it would be better to handle this in the lookup
code, i.e. whether there should be an option for out-of-range colours
to use the colour for the corresponding extreme (min or max).

-- 
Glynn Clements <glynn at gclements.plus.com>

-------------- next part --------------
Index: lib/gis/color_xform.c
===================================================================
--- lib/gis/color_xform.c	(revision 30909)
+++ lib/gis/color_xform.c	(working copy)
@@ -161,8 +161,15 @@
 	y = min + (max - min) * i / samples;
 	G_get_d_raster_color(&y, &red2, &grn2, &blu2, src);
 
-	lx = lmin + (lmax - lmin) * i / samples;
-	x = exp(lx);
+	if (i == 0)
+	    x = min;
+	else if (i == samples)
+	    x = max;
+	else
+	{
+	    lx = lmin + (lmax - lmin) * i / samples;
+	    x = exp(lx);
+	}
 
 	if (i > 0)
 	    G_add_d_raster_color_rule(&prev, red, grn, blu, &x, red2, grn2, blu2, dst);


More information about the grass-dev mailing list