[GRASS-user] integration of sample.c algorithms into r.resample
Glynn Clements
glynn at gclements.plus.com
Mon Aug 14 21:06:25 EDT 2006
Dylan Beaudette wrote:
> After a bit more testing I can see some interesting differences.
>
> using the customized r.bilinear code previously posted:
>
> #set the region
> g.region res=10 -ap
>
> #cutout a sample
> r.mapcalc "c = elev_meters"
>
> #"resample" 10m DEM data to 1m
>
> # 1. via r.bilinear method=nearest
> r.bilinear in=c out=c_n_1m method=nearest
> # 2. via r.bilinear method=bilinear
> r.bilinear in=c out=c_bc_1m method=bicubic
> # 3. via r.bilinear method=bicubic
> r.bilinear in=c out=c_b_1m method=bilinear
>
> #visual comparison of slope computed at 1m
> r.slope.aspect elev=c_b_1m slope=c_b_1m.slope
> r.slope.aspect elev=c_bc_1m slope=c_bc_1m.slope
> r.slope.aspect elev=c_n_1m slope=c_n_1m.slope
>
> #reset the colors for each map
> r.colors map=c_n_1m.slope color=gyr
> r.colors map=c_b_1m.slope color=gyr
> r.colors map=c_bc_1m.slope color=gyr
>
> #see images:
> ##NN
> http://169.237.35.250/~dylan/temp/raster_sampling/c_n_1m.slope.png
>
> ##Bilinear
> http://169.237.35.250/~dylan/temp/raster_sampling/c_b_1m.slope.png
>
> ##Bicubic
> http://169.237.35.250/~dylan/temp/raster_sampling/c_bc_1m.slope.png
>
>
> note that the slope computed from the bicubic algorithm looks very similar to
> the NN slope map -- all computed via the new r.bilinear code. I was under the
> impression that the cubic output would be similar to the bilinear,
> but "smoother"...
The bicubic interpolation formula was taken directly from
lib/gis/sample.c; it wouldn't surprise me if it was wrong.
Hmm.
c = v * (v * (v * (c3 - c2 + c1 - c0) + (c2 - c3 - 2 * c1 + 2 * c0)) + (c2 - c0)) + c1
= v^3 * (c3 - c2 + c1 - c0) + v^2 * (c2 - c3 - 2*c1 + 2*c0) + v * (c2 - c0) + c1
at v=0 => c1
at v=1 => c2
OK.
dc/dv = 3 * v^2 * (c3 - c2 + c1 - c0) + 2 * v * (c2 - c3 - 2*c1 + 2*c0) + (c2 - c0)
= v^2 * (3*c3 - 3*c2 + 3*c1 - 3*c0) + v * (2*c2 - 2*c3 - 4*c1 + 4*c0) + (c2 - c0)
at v=0 => c2 - c0
at v=1 => c3 - c1
Not OK.
The actual gradients should be half that (the distance between c2 and
c0 and between c3 and c1 is 2 grid cells). It's doubling the slope of
the boundary tangents.
We want c = k3 * v^3 + k2 * v^2 + k1 * v + k0 such that:
c(0) = c1
c(1) = c2
c'(0) = (c2 - c0)/2
c'(1) = (c3 - c1)/2
The defintion of c gives:
c(0) = k0
=> k0 = c1
c(1) = k3 + k2 + k1 + k0
=> k3 + k2 + k1 + k0 = c2
Differentiating w.r.t. v giv
c' = 3*k3 * v^2 + 2*k2 * v + k1
c'(0) = k1
=> k1 = (c2 - c0)/2
c'(1) = 3*k3 + 2*k2 + k1
=> 3*k3 + 2*k2 + k1 = (c3 - c1)/2
IOW:
3*k3 + 2*k2 + k1 = (c3 - c1)/2
k3 + k2 + k1 + k0 = c2
k1 = (c2 - c0)/2
k0 = c1
solving gives:
k0 = c1
k1 = c2/2 - c0/2
k2 = -c3/2 + 2*c2 - 5*c1/2 + c0
k3 = c3/2 - 3*c2/2 + 3*c1/2 - c0/2
Try changing the relevant lines to:
DCELL c0 = (u * (u * (u * (c30 - 3*c20 + 3*c10 - c00) + (-c30 + 2*c20 - 5*c10 + 2*c00)) + (c20 - c00)) + 2*c10)/2;
DCELL c1 = (u * (u * (u * (c31 - 3*c21 + 3*c11 - c01) + (-c31 + 2*c21 - 5*c11 + 2*c01)) + (c21 - c01)) + 2*c11)/2;
DCELL c2 = (u * (u * (u * (c32 - 3*c22 + 3*c12 - c02) + (-c32 + 2*c22 - 5*c12 + 2*c02)) + (c22 - c02)) + 2*c12)/2;
DCELL c3 = (u * (u * (u * (c33 - 3*c23 + 3*c13 - c03) + (-c33 + 2*c23 - 5*c13 + 2*c03)) + (c23 - c03)) + 2*c13)/2;
DCELL c = (v * (v * (v * (c3 - 3*c2 + 3*c1 - c0 ) + (-c3 + 2*c2 - 5*c1 + 2*c0 )) + (c2 - c0 )) + 2*c1 )/2;
--
Glynn Clements <glynn at gclements.plus.com>
More information about the grass-user
mailing list