123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- /*-
- * Written by H. Mitasova, I. Kosinovsky, D. Gerdes Fall 1993
- * University of Illinois
- * US Army Construction Engineering Research Lab
- * Copyright 1993, H. Mitasova (University of Illinois),
- * I. Kosinovsky, (USA-CERL), and D.Gerdes (USA-CERL)
- *
- * Modified by H.Mitasova November 1996 to include variable smoothing
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <grass/dataquad.h>
- /* sm added to point structure */
- struct triple *quad_point_new(double x, double y, double z, double sm)
- /* Initializes POINT structure with given arguments */
- {
- struct triple *point;
- if (!(point = (struct triple *)malloc(sizeof(struct triple)))) {
- return NULL;
- }
- point->x = x;
- point->y = y;
- point->z = z;
- point->sm = sm;
- return point;
- }
- struct quaddata *quad_data_new(double x_or, double y_or, double xmax,
- double ymax, int rows, int cols, int n_points,
- int kmax)
- /* Initializes QUADDATA structure with given arguments */
- {
- struct quaddata *data;
- int i;
- if (!(data = (struct quaddata *)malloc(sizeof(struct quaddata)))) {
- return NULL;
- }
- data->x_orig = x_or;
- data->y_orig = y_or;
- data->xmax = xmax;
- data->ymax = ymax;
- data->n_rows = rows;
- data->n_cols = cols;
- data->n_points = n_points;
- data->points =
- (struct triple *)malloc(sizeof(struct triple) * (kmax + 1));
- if (!data->points)
- return NULL;
- for (i = 0; i <= kmax; i++) {
- data->points[i].x = 0.;
- data->points[i].y = 0.;
- data->points[i].z = 0.;
- data->points[i].sm = 0.;
- }
- return data;
- }
- int quad_compare(struct triple *point, struct quaddata *data)
- /* returns the quadrant the point should be inserted in */
- /* called by divide() */
- {
- int cond1, cond2, cond3, cond4, rows, cols;
- double ew_res, ns_res;
- ew_res = (data->xmax - data->x_orig) / data->n_cols;
- ns_res = (data->ymax - data->y_orig) / data->n_rows;
- if (data == NULL)
- return -1;
- if (data->n_rows % 2 == 0) {
- rows = data->n_rows / 2;
- }
- else {
- rows = (int)(data->n_rows / 2) + 1;
- }
- if (data->n_cols % 2 == 0) {
- cols = data->n_cols / 2;
- }
- else {
- cols = (int)(data->n_cols / 2) + 1;
- }
- cond1 = (point->x >= data->x_orig);
- cond2 = (point->x >= data->x_orig + ew_res * cols);
- cond3 = (point->y >= data->y_orig);
- cond4 = (point->y >= data->y_orig + ns_res * rows);
- if (cond1 && cond3) {
- if (cond2 && cond4)
- return NE;
- if (cond2)
- return SE;
- if (cond4)
- return NW;
- return SW;
- }
- else
- return 0;
- }
- int quad_add_data(struct triple *point, struct quaddata *data, double dmin)
- /* Adds POINT to a given DATA . Called by tree function insert_quad() */
- /* and by data function quad_divide_data() */
- {
- int n, i, cond;
- double xx, yy, r;
- cond = 1;
- if (data == NULL) {
- fprintf(stderr, "add_data: data is NULL \n");
- return -5;
- }
- for (i = 0; i < data->n_points; i++) {
- xx = data->points[i].x - point->x;
- yy = data->points[i].y - point->y;
- r = xx * xx + yy * yy;
- if (r <= dmin) {
- cond = 0;
- break;
- }
- }
- if (cond) {
- n = (data->n_points)++;
- data->points[n].x = point->x;
- data->points[n].y = point->y;
- data->points[n].z = point->z;
- data->points[n].sm = point->sm;
- }
- return cond;
- }
- int quad_intersect(struct quaddata *data_inter, struct quaddata *data)
- /* Checks if region defined by DATA intersects the region defined
- by data_inter. Called by tree function MT_region_data() */
- {
- double xmin, xmax, ymin, ymax;
- xmin = data_inter->x_orig;
- xmax = data_inter->xmax;
- ymin = data_inter->y_orig;
- ymax = data_inter->ymax;
- if (((data->x_orig >= xmin) && (data->x_orig <= xmax)
- && (((data->y_orig >= ymin) && (data->y_orig <= ymax))
- || ((ymin >= data->y_orig) && (ymin <= data->ymax))
- )
- )
- || ((xmin >= data->x_orig) && (xmin <= data->xmax)
- && (((ymin >= data->y_orig) && (ymin <= data->ymax))
- || ((data->y_orig >= ymin) && (data->y_orig <= ymax))
- )
- )
- ) {
- return 1;
- }
- else
- return 0;
- }
- int quad_division_check(struct quaddata *data, int kmax)
- /* Checks if DATA needs to be divided. If data->points is empty,
- returns -1; if its not empty but there aren't enough points
- in DATA for division returns 0. Othervise (if its not empty and
- there are too many points) returns 1. Called by MT_insert() */
- {
- if (data->points == NULL)
- return -1;
- if (data->n_points < kmax)
- return 0;
- else
- return 1;
- }
- struct quaddata **quad_divide_data(struct quaddata *data, int kmax,
- double dmin)
- /* Divides DATA into 4 new datas reinserting data->points in
- them by calling data function quad_compare() to detrmine
- were to insert. Called by MT_divide(). Returns array of 4 new datas */
- {
- struct quaddata **datas;
- int cols1, cols2, rows1, rows2, i; /*j1, j2, jmin = 0; */
- double dx, dy; /* x2, y2, dist, mindist; */
- double xr, xm, xl, yr, ym, yl; /* left, right, middle coord */
- double ew_res, ns_res;
- ew_res = (data->xmax - data->x_orig) / data->n_cols;
- ns_res = (data->ymax - data->y_orig) / data->n_rows;
- if ((data->n_cols <= 1) || (data->n_rows <= 1)) {
- fprintf(stderr,
- "Points are too concentrated -- please increase DMIN\n");
- exit(0);
- }
- if (data->n_cols % 2 == 0) {
- cols1 = data->n_cols / 2;
- cols2 = cols1;
- }
- else {
- cols2 = (int)(data->n_cols / 2);
- cols1 = cols2 + 1;
- }
- if (data->n_rows % 2 == 0) {
- rows1 = data->n_rows / 2;
- rows2 = rows1;
- }
- else {
- rows2 = (int)(data->n_rows / 2);
- rows1 = rows2 + 1;
- }
- dx = cols1 * ew_res;
- dy = rows1 * ns_res;
- xl = data->x_orig;
- xm = xl + dx;
- xr = data->xmax;
- yl = data->y_orig;
- ym = yl + dy;
- yr = data->ymax;
- if (!(datas = (struct quaddata **)malloc(sizeof(struct quaddata *) * 5))) {
- return NULL;
- }
- datas[NE] = quad_data_new(xm, ym, xr, yr, rows2, cols2, 0, kmax);
- datas[SW] = quad_data_new(xl, yl, xm, ym, rows1, cols1, 0, kmax);
- datas[SE] = quad_data_new(xm, yl, xr, ym, rows1, cols2, 0, kmax);
- datas[NW] = quad_data_new(xl, ym, xm, yr, rows2, cols1, 0, kmax);
- for (i = 0; i < data->n_points; i++) {
- switch (quad_compare(data->points + i, data)) {
- case SW:
- {
- quad_add_data(data->points + i, datas[SW], dmin);
- break;
- }
- case SE:
- {
- quad_add_data(data->points + i, datas[SE], dmin);
- break;
- }
- case NW:
- {
- quad_add_data(data->points + i, datas[NW], dmin);
- break;
- }
- case NE:
- {
- quad_add_data(data->points + i, datas[NE], dmin);
- break;
- }
- }
- }
- data->points = NULL;
- return datas;
- }
- int
- quad_get_points(struct quaddata *data_inter, struct quaddata *data, int MAX)
- /* Gets such points from DATA that lie within region determined by
- data_inter. Called by tree function region_data(). */
- {
- int i, ind;
- int n = 0;
- int l = 0;
- double xmin, xmax, ymin, ymax;
- struct triple *point;
- xmin = data_inter->x_orig;
- xmax = data_inter->xmax;
- ymin = data_inter->y_orig;
- ymax = data_inter->ymax;
- for (i = 0; i < data->n_points; i++) {
- point = data->points + i;
- if (l >= MAX)
- return MAX + 1;
- if ((point->x > xmin) && (point->x < xmax)
- && (point->y > ymin) && (point->y < ymax)) {
- ind = data_inter->n_points++;
- data_inter->points[ind].x = point->x;
- data_inter->points[ind].y = point->y;
- data_inter->points[ind].z = point->z;
- data_inter->points[ind].sm = point->sm;
- l = l + 1;
- }
- }
- n = l;
- return (n);
- }
|