sandbox/terrain.h
This uses the kdt module to reconstruct the terrain from the list of kdt databases specified
#include <stdarg.h>
#include <kdt/kdt.h>
#ifdef _OPENMP
# define NPROC omp_get_max_threads()
#else
# define NPROC 1
#endif
typedef struct {
*** kdt;
Kdt scalar n, dmin, dmax;
} Terrain;
Terrain * _terrain = NULL;
int _nterrain = 0;
In order to use the kdt_query_sum it is necessary to specify two functions, an includes function and an intersects function.
The includes function determines whether the cell specified by point p (with centre (x,y) and cell size delta includes a given kdt rectangle
static int includes (KdtRect rect, Point * p)
{
= *p;
Point point /= 2.;
delta return (rect[0].l >= x - delta && rect[0].h <= x + delta &&
[1].l >= y - delta && rect[1].h <= y + delta);
rect}
The intersects function determines whether there is any intersection between the cell specified by point p and the kdt rectangle
static int intersects (KdtRect rect, Point * p)
{
= *p;
Point point /= 2.;
delta return (rect[0].l <= x + delta && rect[0].h >= x - delta &&
[1].l <= y + delta && rect[1].h >= y - delta);
rect}
static void reconstruct_terrain (Point point, scalar zb)
{
;
KdtSum s(&s);
kdt_sum_init /= 2.;
delta = {{x - delta, x + delta},
KdtRect rect {y - delta, y + delta}};
for (Kdt ** kdt = _terrain[zb].kdt[pid()]; *kdt; kdt++)
(*kdt,
kdt_query_sum (KdtCheck) includes,
(KdtCheck) intersects, &point,
, &s);
rect(_terrain[zb].n,0,0) = s.n;
valif (s.w > 0.) {
[] = s.H0/s.w;
zb(_terrain[zb].dmin,0,0) = s.Hmin;
val(_terrain[zb].dmax,0,0) = s.Hmax;
val}
else {
/* not enough points in database, use bilinear interpolation
from coarser level instead */
if (level > 0)
[] = (9.*coarse(zb,0,0) +
zb3.*(coarse(zb,child.x,0) + coarse(zb,0,child.y)) +
(zb,child.x,child.y))/16.;
coarse
else[] = 0.; // no points at level 0!
zb(_terrain[zb].dmin,0,0) = nodata;
val(_terrain[zb].dmax,0,0) = nodata;
val}
}
static void refine_terrain (Point point, scalar zb)
{
foreach_child()
reconstruct_terrain (point, zb);
}
void terrain (scalar zb, ...)
{
if (zb >= _nterrain) {
= realloc (_terrain, sizeof (Terrain)*(zb + 1));
_terrain = zb + 1;
_nterrain }
[zb].kdt = calloc (NPROC, sizeof (Kdt **));
_terrain
int nt = 0;
va_list ap;
(ap, zb);
va_start char * name;
while ((name = va_arg (ap, char *)))
for (int i = 0; i < NPROC; i++) {
** kdt = _terrain[zb].kdt[i];
Kdt [zb].kdt[i] = kdt = realloc (kdt, sizeof(Kdt *)*(nt + 2));
_terrain[nt] = kdt_new();
kdt[nt + 1] = NULL;
kdtif (kdt_open (kdt[nt], name)) {
fprintf (stderr, "terrain: could not open terrain database '%s'\n",
);
nameexit (1);
}
}
(ap);
va_end
.refine = refine_terrain;
zbscalar n = new scalar;
.refine = refine_none;
n.coarsen = refine_none;
n[zb].n = n;
_terrainscalar dmin = new scalar;
.refine = refine_none;
dmin.coarsen = refine_none;
dmin[zb].dmin = dmin;
_terrainscalar dmax = new scalar;
.refine = refine_none;
dmax.coarsen = refine_none;
dmax[zb].dmax = dmax;
_terrain
({zb, n, dmin, dmax});
trash for (int l = 0; l <= depth(); l++) {
(l)
foreach_level reconstruct_terrain (point, zb);
({zb}, l);
boundary_level }
}