/* **************************************************************************** * * MODULE: s.vol.rst: program for 3D(volume) interpolation and geometry * analysis from scattered point data using regularized spline * with tension * * AUTHOR(S): Original program (1989) and various modifications: * Lubos Mitas * * GRASS 4.2, GRASS 5.0 version and modifications: * H. Mitasova, I. Kosinovsky, D. Gerdes, J. Hofierka * * PURPOSE: s.vol.rst interpolates the values to 3-dimensional grid from * point data (climatic stations, drill holes etc.) given in a * sites file named input. Output grid3 file is elev. * Regularized spline with tension is used for the * interpolation. * * COPYRIGHT: (C) 1989, 1993, 2000 L. Mitas, H. Mitasova, * I. Kosinovsky, D. Gerdes, J. Hofierka * * This program is free software under the GNU General Public * License (>=v2). Read the file COPYING that comes with GRASS * for details. * *****************************************************************************/ #include #include #include #include #include "oct.h" #include "externs.h" #include "dataoct.h" struct octfunc * OT_functions_new (int (*compare)(), VOID_T **(*divide_data)(), int (*add_data)(), int (*intersect)(), int (*division_check)(), int (*get_points)()) /* Initializes FUNCTIONS structure with given arguments*/ { struct octfunc *functions; if (!(functions = (struct octfunc *) G_malloc (sizeof (struct octfunc)))) { return NULL; } functions->compare = compare; functions->divide_data = divide_data; functions->add_data = add_data; functions->intersect = intersect; functions->division_check = division_check; functions->get_points = get_points; return functions; } struct octtree * OT_tree_new (VOID_T *data, struct octtree **leafs, struct octtree *parent, struct octfunc *functions, int octant) /*Initializes TREE using given arguments*/ { struct octtree *tree; if (!(tree = (struct octtree *) G_malloc (sizeof (struct octtree)))) { return NULL; } tree->data = data; tree->leafs = leafs; tree->parent = parent; tree->functions = functions; tree->octant = octant; return tree; } int OT_insert_oct (struct quadruple *point, struct octtree *tree) { int j=0, i, k, comp; if (tree == NULL) { fprintf(stderr,"insert: tree is NULL\n"); return -5; } if (tree->data == NULL) { fprintf(stderr,"insert: tree->data is NULL\n"); return -5; } i = tree->functions->division_check (tree->data); if (i<=0) { if (i==-1) { comp=tree->functions->compare(point,tree->data); if ((comp<1)||(comp>NUMLEAFS)) return -3; j=OT_insert_oct(point, tree->leafs[comp-1]); } else { if (i==0) { j=tree->functions->add_data (point, tree->data); } } } else { k=OT_divide_oct(tree); if(k==1) j=OT_insert_oct(point,tree); /* DPG hack */ if (k == -3) { static int once = 0; if (!once) { fprintf (stderr, "Point out of range!\n"); once = 1; } } if(k<0) return k; } return j; } int OT_divide_oct (struct octtree *tree) { int i; VOID_T **datas; struct octtree *par; struct octtree **leafs; datas=tree->functions->divide_data(tree->data); if (datas==NULL) { fprintf(stderr,"datas is NULL\n"); return -7; } par = tree; leafs = (struct octtree **)G_malloc (sizeof(struct octtree * ) *NUMLEAFS); for (i=1;i<=NUMLEAFS;i++) { leafs[i-1]=OT_tree_new(datas[i],NULL,par,tree->functions,i); } tree->leafs=leafs; return 1; } int OT_region_data (struct octtree *tree, double xmin, double xmax, double ymin, double ymax, double zmin, double zmax, struct quadruple *points, int MAX) /* max number of points we can add (KMAX2) */ /* note: this KMAX2 can be larger then KMAX */ { int n = 0, j; if (tree == NULL) { fprintf(stderr,"OT_region_data: tree is NULL\n"); return n; } if (tree->data == NULL) { fprintf(stderr,"OT_region_data: tree is NULL\n"); return n; } if (tree->functions->intersect (xmin, xmax, ymin, ymax, zmin, zmax, tree->data)) { if (tree->leafs != NULL) { for(j=0;jleafs[j], xmin, xmax, ymin, ymax, zmin, zmax, points + n, MAX-n)) > MAX) return n; } } else { n=tree->functions->get_points(points,tree->data, xmin,xmax,ymin,ymax,zmin,zmax,MAX); } return n; } return 0; }