interp2d.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /*-
  2. *
  3. * Original program and various modifications:
  4. * Lubos Mitas
  5. *
  6. * GRASS4.1 version of the program and GRASS4.2 modifications:
  7. * H. Mitasova,
  8. * I. Kosinovsky, D. Gerdes
  9. * D. McCauley
  10. *
  11. * Copyright 1993, 1995:
  12. * L. Mitas ,
  13. * H. Mitasova,
  14. * I. Kosinovsky,
  15. * D.Gerdes
  16. * D. McCauley
  17. *
  18. * modified by McCauley in August 1995
  19. * modified by Mitasova in August 1995, Nov. 1996
  20. * bug fixes(mask) and modif. for variable smoothing Mitasova Jan 1997
  21. *
  22. */
  23. #include <stdio.h>
  24. #include <math.h>
  25. #include <unistd.h>
  26. #include <grass/gis.h>
  27. #include <grass/raster.h>
  28. #include <grass/glocale.h>
  29. #include <grass/bitmap.h>
  30. #include <grass/interpf.h>
  31. #define CEULER .57721566
  32. int IL_grid_calc_2d(struct interp_params *params, struct quaddata *data, /* given segment */
  33. struct BM *bitmask, /* bitmask */
  34. double zmin, double zmax, /* min and max input z-values */
  35. double *zminac, double *zmaxac, /* min and max interp. z-values */
  36. double *gmin, double *gmax, /* min and max inperp. slope val. */
  37. double *c1min, double *c1max, double *c2min, double *c2max, /* min and max interp. curv. val. */
  38. double *ertot, /* total interplating func. error */
  39. double *b, /* solutions of linear equations */
  40. off_t offset1, /* offset for temp file writing */
  41. double dnorm)
  42. /*
  43. * Calculates grid for the given segment represented by data (contains
  44. * n_rows, n_cols, ew_res,ns_res, and all points inside + overlap) using
  45. * solutions of system of lin. equations and interpolating functions
  46. * interp() and interpder(). Also calls secpar() to compute slope, aspect
  47. * and curvatures if required.
  48. */
  49. {
  50. /*
  51. * C C INTERPOLATION BY FUNCTIONAL METHOD : TPS + complete regul.
  52. * c
  53. */
  54. double x_or = data->x_orig;
  55. double y_or = data->y_orig;
  56. int n_rows = data->n_rows;
  57. int n_cols = data->n_cols;
  58. int n_points = data->n_points;
  59. struct triple *points;
  60. static double *w2 = NULL;
  61. static double *w = NULL;
  62. int cond1, cond2;
  63. double r;
  64. double stepix, stepiy, xx, xg, yg, xx2;
  65. double rfsta2, /* cons, cons1, */ wm, dx, dy, dxx, dyy, dxy, h, bmgd1,
  66. bmgd2;
  67. double r2, gd1, gd2; /* for interpder() */
  68. int n1, k, l, m;
  69. int ngstc, nszc, ngstr, nszr;
  70. double zz;
  71. int bmask = 1;
  72. static int first_time_z = 1;
  73. off_t offset, offset2;
  74. double fstar2 = params->fi * params->fi / 4.;
  75. double tfsta2, tfstad;
  76. double ns_res, ew_res;
  77. double rsin = 0, rcos = 0, teta, scale = 0; /*anisotropy parameters - added by JH 2002 */
  78. double xxr, yyr;
  79. if (params->theta) {
  80. teta = params->theta / 57.295779; /* deg to rad */
  81. rsin = sin(teta);
  82. rcos = cos(teta);
  83. }
  84. if (params->scalex)
  85. scale = params->scalex;
  86. ns_res = (((struct quaddata *)(data))->ymax -
  87. ((struct quaddata *)(data))->y_orig) / data->n_rows;
  88. ew_res = (((struct quaddata *)(data))->xmax -
  89. ((struct quaddata *)(data))->x_orig) / data->n_cols;
  90. /* tfsta2 = fstar2 * 2.; modified after removing normalization of z */
  91. tfsta2 = (fstar2 * 2.) / dnorm;
  92. tfstad = tfsta2 / dnorm;
  93. points = data->points;
  94. /*
  95. * normalization
  96. */
  97. stepix = ew_res / dnorm;
  98. stepiy = ns_res / dnorm;
  99. cond2 = ((params->adxx != NULL) || (params->adyy != NULL) ||
  100. (params->adxy != NULL));
  101. cond1 = ((params->adx != NULL) || (params->ady != NULL) || cond2);
  102. if (!w) {
  103. if (!(w = (double *)G_malloc(sizeof(double) * (params->KMAX2 + 9)))) {
  104. G_warning(_("Out of memory"));
  105. return -1;
  106. }
  107. }
  108. if (!w2) {
  109. if (!(w2 = (double *)G_malloc(sizeof(double) * (params->KMAX2 + 9)))) {
  110. G_warning(_("Out of memory"));
  111. return -1;
  112. }
  113. }
  114. n1 = n_points + 1;
  115. /*
  116. * C C INTERPOLATION * MOST INNER LOOPS ! C
  117. */
  118. ngstc = (int)(x_or / ew_res + 0.5) + 1;
  119. nszc = ngstc + n_cols - 1;
  120. ngstr = (int)(y_or / ns_res + 0.5) + 1;
  121. nszr = ngstr + n_rows - 1;
  122. for (k = ngstr; k <= nszr; k++) {
  123. offset = offset1 * (k - 1); /* rows offset */
  124. yg = (k - ngstr) * stepiy + stepiy / 2.; /* fixed by J.H. in July 01 */
  125. for (m = 1; m <= n_points; m++) {
  126. wm = yg - points[m - 1].y;
  127. w[m] = wm;
  128. w2[m] = wm * wm;
  129. }
  130. for (l = ngstc; l <= nszc; l++) {
  131. if (bitmask != NULL)
  132. /* if(params->maskmap != NULL) PK Apr 03 MASK support */
  133. bmask = BM_get(bitmask, l - 1, k - 1); /*fixed by helena jan 97 */
  134. /* if(bmask==0 || bmask==-1) fprintf(stderr, "bmask=%d, at (%d,%d)\n", bmask, l, k); */
  135. xg = (l - ngstc) * stepix + stepix / 2.; /*fixed by J.H. in July 01 */
  136. dx = 0.;
  137. dy = 0.;
  138. dxx = 0.;
  139. dyy = 0.;
  140. dxy = 0.;
  141. zz = 0.;
  142. if (bmask == 1) { /* compute everything for area which is
  143. * not masked out */
  144. h = b[0];
  145. for (m = 1; m <= n_points; m++) {
  146. xx = xg - points[m - 1].x;
  147. if ((params->theta) && (params->scalex)) {
  148. /* we run anisotropy */
  149. xxr = xx * rcos + w[m] * rsin;
  150. yyr = w[m] * rcos - xx * rsin;
  151. xx2 = xxr * xxr;
  152. w2[m] = yyr * yyr;
  153. r2 = scale * xx2 + w2[m];
  154. r = r2;
  155. rfsta2 = scale * xx2 + w2[m];
  156. }
  157. else {
  158. xx2 = xx * xx;
  159. r2 = xx2 + w2[m];
  160. r = r2;
  161. rfsta2 = xx2 + w2[m];
  162. }
  163. h = h + b[m] * params->interp(r, params->fi);
  164. if (cond1) {
  165. if (!params->interpder(r, params->fi, &gd1, &gd2))
  166. return -1;
  167. bmgd1 = b[m] * gd1;
  168. dx = dx + bmgd1 * xx;
  169. dy = dy + bmgd1 * w[m];
  170. if (cond2) {
  171. bmgd2 = b[m] * gd2;
  172. dxx = dxx + bmgd2 * xx2 + bmgd1;
  173. dyy = dyy + bmgd2 * w2[m] + bmgd1;
  174. dxy = dxy + bmgd2 * xx * w[m];
  175. }
  176. }
  177. }
  178. /* zz = (h * dnorm) + zmin; replaced by helena jan. 97 due to removing norma
  179. lization of z and zm in segmen2d.c */
  180. zz = h + zmin;
  181. if (first_time_z) {
  182. first_time_z = 0;
  183. *zmaxac = *zminac = zz;
  184. }
  185. *zmaxac = amax1(zz, *zmaxac);
  186. *zminac = amin1(zz, *zminac);
  187. if ((zz > zmax + 0.1 * (zmax - zmin))
  188. || (zz < zmin - 0.1 * (zmax - zmin))) {
  189. static int once = 0;
  190. if (!once) {
  191. once = 1;
  192. G_warning(_("Overshoot - increase in tension suggested. "
  193. "Overshoot occures at (%d,%d) cell. "
  194. "Z-value %f, zmin %f, zmax %f."),
  195. l, k, zz, zmin, zmax);
  196. }
  197. }
  198. params->az[l] = (FCELL) zz;
  199. if (cond1) {
  200. params->adx[l] = (FCELL) (-dx * tfsta2);
  201. params->ady[l] = (FCELL) (-dy * tfsta2);
  202. if (cond2) {
  203. params->adxx[l] = (FCELL) (-dxx * tfstad);
  204. params->adyy[l] = (FCELL) (-dyy * tfstad);
  205. params->adxy[l] = (FCELL) (-dxy * tfstad);
  206. }
  207. }
  208. }
  209. else {
  210. Rast_set_d_null_value(params->az + l, 1);
  211. /* fprintf (stderr, "zz=%f, az[l]=%f, c=%d\n", zz, params->az[l], l); */
  212. if (cond1) {
  213. Rast_set_d_null_value(params->adx + l, 1);
  214. Rast_set_d_null_value(params->ady + l, 1);
  215. if (cond2) {
  216. Rast_set_d_null_value(params->adxx + l, 1);
  217. Rast_set_d_null_value(params->adyy + l, 1);
  218. Rast_set_d_null_value(params->adxy + l, 1);
  219. }
  220. }
  221. }
  222. }
  223. if (cond1 && (params->deriv != 1)) {
  224. if (params->secpar(params, ngstc, nszc, k, bitmask,
  225. gmin, gmax, c1min, c1max, c2min, c2max, cond1,
  226. cond2) < 0)
  227. return -1;
  228. }
  229. offset2 = (offset + ngstc - 1) * sizeof(FCELL);
  230. if (params->wr_temp(params, ngstc, nszc, offset2) < 0)
  231. return -1;
  232. }
  233. return 1;
  234. }