InterpSpline.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /***********************************************************************
  2. *
  3. * MODULE: lidarlib
  4. *
  5. * AUTHOR(S): Roberto Antolin
  6. *
  7. * PURPOSE: LIDAR Spline Interpolation
  8. *
  9. * COPYRIGHT: (C) 2006 by Politecnico di Milano -
  10. * Polo Regionale di Como
  11. *
  12. * This program is free software under the
  13. * GNU General Public License (>=v2).
  14. * Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. **************************************************************************/
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <float.h>
  21. #include <math.h>
  22. #include <string.h>
  23. #include <grass/lidar.h>
  24. /*----------------------------------------------------------------------------*/
  25. /* Abscissa node index computation */
  26. void node_x(double x, int *i_x, double *csi_x, double xMin, double deltaX)
  27. {
  28. *i_x = (int)((x - xMin) / deltaX);
  29. *csi_x = (double)((x - xMin) - (*i_x * deltaX));
  30. return;
  31. }
  32. /*----------------------------------------------------------------------------*/
  33. /* Ordinate node index computation */
  34. void node_y(double y, int *i_y, double *csi_y, double yMin, double deltaY)
  35. {
  36. *i_y = (int)((y - yMin) / deltaY);
  37. *csi_y = (double)((y - yMin) - (*i_y * deltaY));
  38. return;
  39. }
  40. /*----------------------------------------------------------------------------*/
  41. /* Node order computation */
  42. int order(int i_x, int i_y, int yNum)
  43. {
  44. return (i_y + i_x * yNum);
  45. }
  46. /*----------------------------------------------------------------------------*/
  47. /* Design matrix coefficients computation */
  48. double phi_3(double csi)
  49. {
  50. return ((pow(2 - csi, 3.) - pow(1 - csi, 3.) * 4) / 6.);
  51. }
  52. double phi_4(double csi)
  53. {
  54. return (pow(2 - csi, 3.) / 6.);
  55. }
  56. double phi_33(double csi_x, double csi_y)
  57. {
  58. return (phi_3(csi_x) * phi_3(csi_y));
  59. }
  60. double phi_34(double csi_x, double csi_y)
  61. {
  62. return (phi_3(csi_x) * phi_4(csi_y));
  63. }
  64. double phi_43(double csi_x, double csi_y)
  65. {
  66. return (phi_4(csi_x) * phi_3(csi_y));
  67. }
  68. double phi_44(double csi_x, double csi_y)
  69. {
  70. return (phi_4(csi_x) * phi_4(csi_y));
  71. }
  72. double phi(double csi_x, double csi_y)
  73. {
  74. return ((1 - csi_x) * (1 - csi_y));
  75. }
  76. /*----------------------------------------------------------------------------*/
  77. /* Normal system computation for bicubic spline interpolation */
  78. void normalDefBicubic(double **N, double *TN, double *Q, double **obsVect,
  79. double deltaX, double deltaY, int xNum, int yNum,
  80. double xMin, double yMin, int obsNum, int parNum,
  81. int BW)
  82. {
  83. int i, k, h, m, n, n0; /* counters */
  84. double alpha[4][4]; /* coefficients */
  85. int i_x; /* x = (xMin + (i_x * deltaX) + csi_x) */
  86. double csi_x;
  87. int i_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
  88. double csi_y;
  89. /*--------------------------------------*/
  90. for (k = 0; k < parNum; k++) {
  91. for (h = 0; h < BW; h++)
  92. N[k][h] = 0.; /* Normal matrix inizialization */
  93. TN[k] = 0.; /* Normal vector inizialization */
  94. }
  95. /*--------------------------------------*/
  96. for (i = 0; i < obsNum; i++) {
  97. node_x(obsVect[i][0], &i_x, &csi_x, xMin, deltaX);
  98. node_y(obsVect[i][1], &i_y, &csi_y, yMin, deltaY);
  99. if ((i_x >= -2) && (i_x <= xNum) && (i_y >= -2) && (i_y <= yNum)) {
  100. csi_x = csi_x / deltaX;
  101. csi_y = csi_y / deltaY;
  102. alpha[0][0] = phi_44(1 + csi_x, 1 + csi_y);
  103. alpha[0][1] = phi_43(1 + csi_x, csi_y);
  104. alpha[0][2] = phi_43(1 + csi_x, 1 - csi_y);
  105. alpha[0][3] = phi_44(1 + csi_x, 2 - csi_y);
  106. alpha[1][0] = phi_34(csi_x, 1 + csi_y);
  107. alpha[1][1] = phi_33(csi_x, csi_y);
  108. alpha[1][2] = phi_33(csi_x, 1 - csi_y);
  109. alpha[1][3] = phi_34(csi_x, 2 - csi_y);
  110. alpha[2][0] = phi_34(1 - csi_x, 1 + csi_y);
  111. alpha[2][1] = phi_33(1 - csi_x, csi_y);
  112. alpha[2][2] = phi_33(1 - csi_x, 1 - csi_y);
  113. alpha[2][3] = phi_34(1 - csi_x, 2 - csi_y);
  114. alpha[3][0] = phi_44(2 - csi_x, 1 + csi_y);
  115. alpha[3][1] = phi_43(2 - csi_x, csi_y);
  116. alpha[3][2] = phi_43(2 - csi_x, 1 - csi_y);
  117. alpha[3][3] = phi_44(2 - csi_x, 2 - csi_y);
  118. for (k = -1; k <= 2; k++) {
  119. for (h = -1; h <= 2; h++) {
  120. if (((i_x + k) >= 0) && ((i_x + k) < xNum) &&
  121. ((i_y + h) >= 0) && ((i_y + h) < yNum)) {
  122. for (m = k; m <= 2; m++) {
  123. if (m == k)
  124. n0 = h;
  125. else
  126. n0 = -1;
  127. for (n = n0; n <= 2; n++) {
  128. if (((i_x + m) >= 0) && ((i_x + m) < xNum) &&
  129. ((i_y + n) >= 0) && ((i_y + n) < yNum)) {
  130. N[order(i_x + k, i_y + h, yNum)][order
  131. (i_x + m,
  132. i_y + n,
  133. yNum) -
  134. order(i_x
  135. +
  136. k,
  137. i_y
  138. +
  139. h,
  140. yNum)]
  141. +=
  142. alpha[k + 1][h +
  143. 1] * (1 / Q[i]) *
  144. alpha[m + 1][n + 1];
  145. /* 1/Q[i] only refers to the variances */
  146. }
  147. }
  148. }
  149. TN[order(i_x + k, i_y + h, yNum)] +=
  150. obsVect[i][2] * (1 / Q[i]) * alpha[k + 1][h + 1];
  151. }
  152. }
  153. }
  154. }
  155. }
  156. return;
  157. }
  158. /*----------------------------------------------------------------------------*/
  159. /* Normal system correction - Introduzione della correzione dovuta alle
  160. pseudosservazioni (Tykonov) - LAPALCIANO - */
  161. void nCorrectLapl(double **N, double lambda, int xNum, int yNum,
  162. double deltaX, double deltaY)
  163. {
  164. int i_x, i_y; /* counters */
  165. int k, h, m, n, n0; /* counters */
  166. double alpha[5][5]; /* coefficients */
  167. double lambdaX, lambdaY;
  168. /*--------------------------------------*/
  169. lambdaX = lambda * (deltaY / deltaX);
  170. lambdaY = lambda * (deltaX / deltaY);
  171. alpha[0][0] = 0;
  172. alpha[0][1] = lambdaX * (1 / 36.); /* There is lambda because Q^(-1) contains 1/(1/lambda) */
  173. alpha[0][2] = lambdaX * (1 / 9.);
  174. alpha[0][3] = lambdaX * (1 / 36.);
  175. alpha[0][4] = 0;
  176. alpha[1][0] = lambdaY * (1 / 36.);
  177. alpha[1][1] = lambdaX * (1 / 18.) + lambdaY * (1 / 18.);
  178. alpha[1][2] = lambdaX * (2 / 9.) - lambdaY * (1 / 6.);
  179. alpha[1][3] = lambdaX * (1 / 18.) + lambdaY * (1 / 18.);
  180. alpha[1][4] = lambdaY * (1 / 36.);
  181. alpha[2][0] = lambdaY * (1 / 9.);
  182. alpha[2][1] = -lambdaX * (1 / 6.) + lambdaY * (2 / 9.);
  183. alpha[2][2] = -lambdaX * (2 / 3.) - lambdaY * (2 / 3.);
  184. alpha[2][3] = -lambdaX * (1 / 6.) + lambdaY * (2 / 9.);
  185. alpha[2][4] = lambdaY * (1 / 9.);
  186. alpha[3][0] = lambdaY * (1 / 36.);
  187. alpha[3][1] = lambdaX * (1 / 18.) + lambdaY * (1 / 18.);
  188. alpha[3][2] = lambdaX * (2 / 9.) - lambdaY * (1 / 6.);
  189. alpha[3][3] = lambdaX * (1 / 18.) + lambdaY * (1 / 18.);
  190. alpha[3][4] = lambdaY * (1 / 36.);
  191. alpha[4][0] = 0;
  192. alpha[4][1] = lambdaX * (1 / 36.);
  193. alpha[4][2] = lambdaX * (1 / 9.);
  194. alpha[4][3] = lambdaX * (1 / 36.);
  195. alpha[4][4] = 0;
  196. for (i_x = 0; i_x < xNum; i_x++) {
  197. for (i_y = 0; i_y < yNum; i_y++) {
  198. for (k = -2; k <= 2; k++) {
  199. for (h = -2; h <= 2; h++) {
  200. if (((i_x + k) >= 0) && ((i_x + k) < xNum) &&
  201. ((i_y + h) >= 0) && ((i_y + h) < yNum)) {
  202. for (m = k; m <= 2; m++) {
  203. if (m == k)
  204. n0 = h;
  205. else
  206. n0 = -2;
  207. for (n = n0; n <= 2; n++) {
  208. if (((i_x + m) >= 0) &&
  209. ((i_x + m) <= (xNum - 1)) &&
  210. ((i_y + n) >= 0) &&
  211. ((i_y + n) <= (yNum - 1))) {
  212. if ((alpha[k + 2][h + 2] != 0) &&
  213. (alpha[m + 2][n + 2] != 0)) {
  214. N[order(i_x + k, i_y + h, yNum)][order
  215. (i_x
  216. + m,
  217. i_y
  218. + n,
  219. yNum)
  220. -
  221. order
  222. (i_x
  223. + k,
  224. i_y
  225. + h,
  226. yNum)]
  227. +=
  228. alpha[k + 2][h + 2] * alpha[m +
  229. 2][n +
  230. 2];
  231. }
  232. }
  233. }
  234. }
  235. }
  236. }
  237. }
  238. }
  239. }
  240. return;
  241. }
  242. /*----------------------------------------------------------------------------*/
  243. /* Normal system computation for bilinear spline interpolation */
  244. void normalDefBilin(double **N, double *TN, double *Q, double **obsVect,
  245. double deltaX, double deltaY, int xNum, int yNum,
  246. double xMin, double yMin, int obsNum, int parNum, int BW)
  247. {
  248. int i, k, h, m, n, n0; /* counters */
  249. double alpha[2][2]; /* coefficients */
  250. int i_x; /* x = (xMin + (i_x * deltaX) + csi_x) */
  251. double csi_x;
  252. int i_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
  253. double csi_y;
  254. /*--------------------------------------*/
  255. for (k = 0; k < parNum; k++) {
  256. for (h = 0; h < BW; h++)
  257. N[k][h] = 0.; /* Normal matrix inizialization */
  258. TN[k] = 0.; /* Normal vector inizialization */
  259. }
  260. /*--------------------------------------*/
  261. for (i = 0; i < obsNum; i++) {
  262. node_x(obsVect[i][0], &i_x, &csi_x, xMin, deltaX);
  263. node_y(obsVect[i][1], &i_y, &csi_y, yMin, deltaY);
  264. if ((i_x >= -1) && (i_x < xNum) && (i_y >= -1) && (i_y < yNum)) {
  265. csi_x = csi_x / deltaX;
  266. csi_y = csi_y / deltaY;
  267. alpha[0][0] = phi(csi_x, csi_y);
  268. alpha[0][1] = phi(csi_x, 1 - csi_y);
  269. alpha[1][0] = phi(1 - csi_x, csi_y);
  270. alpha[1][1] = phi(1 - csi_x, 1 - csi_y);
  271. for (k = 0; k <= 1; k++) {
  272. for (h = 0; h <= 1; h++) {
  273. if (((i_x + k) >= 0) && ((i_x + k) <= (xNum - 1)) &&
  274. ((i_y + h) >= 0) && ((i_y + h) <= (yNum - 1))) {
  275. for (m = k; m <= 1; m++) {
  276. if (m == k)
  277. n0 = h;
  278. else
  279. n0 = 0;
  280. for (n = n0; n <= 1; n++) {
  281. if (((i_x + m) >= 0) && ((i_x + m) < xNum) &&
  282. ((i_y + n) >= 0) && ((i_y + n) < yNum)) {
  283. N[order(i_x + k, i_y + h, yNum)][order
  284. (i_x + m,
  285. i_y + n,
  286. yNum) -
  287. order(i_x
  288. +
  289. k,
  290. i_y
  291. +
  292. h,
  293. yNum)]
  294. +=
  295. alpha[k][h] * (1 / Q[i]) *
  296. alpha[m][n];
  297. /* 1/Q[i] only refers to the variances */
  298. }
  299. }
  300. }
  301. TN[order(i_x + k, i_y + h, yNum)] +=
  302. obsVect[i][2] * (1 / Q[i]) * alpha[k][h];
  303. }
  304. }
  305. }
  306. }
  307. }
  308. return;
  309. }
  310. /*----------------------------------------------------------------------------*/
  311. /* Normal system correction - Introduzione della correzione dovuta alle
  312. pseudosservazioni (Tykonov) - GRADIENTE - */
  313. #ifdef notdef
  314. void nCorrectGrad(double **N, double lambda, int xNum, int yNum,
  315. double deltaX, double deltaY)
  316. {
  317. int i;
  318. int parNum;
  319. double alpha[3];
  320. double lambdaX, lambdaY;
  321. lambdaX = lambda * (deltaY / deltaX);
  322. lambdaY = lambda * (deltaX / deltaY);
  323. parNum = xNum * yNum;
  324. alpha[0] = lambdaX / 2. + lambdaY / 2.;
  325. alpha[1] = -lambdaX / 4.;
  326. alpha[2] = -lambdaY / 4.;
  327. for (i = 0; i < parNum; i++) {
  328. N[i][0] += alpha[0];
  329. if ((i + 2) < parNum)
  330. N[i][2] += alpha[2];
  331. if ((i + 2 * yNum) < parNum)
  332. N[i][2 * yNum] += alpha[1];
  333. }
  334. }
  335. #endif
  336. /*1-DELTA discretization */
  337. void nCorrectGrad(double **N, double lambda, int xNum, int yNum,
  338. double deltaX, double deltaY)
  339. {
  340. int i;
  341. int parNum;
  342. double alpha[3];
  343. double lambdaX, lambdaY;
  344. lambdaX = lambda * (deltaY / deltaX);
  345. lambdaY = lambda * (deltaX / deltaY);
  346. parNum = xNum * yNum;
  347. alpha[0] = 2 * lambdaX + 2 * lambdaY;
  348. alpha[1] = -lambdaX;
  349. alpha[2] = -lambdaY;
  350. for (i = 0; i < parNum; i++) {
  351. N[i][0] += alpha[0];
  352. if ((i + 1) < parNum)
  353. N[i][1] += alpha[2];
  354. if ((i + 1 * yNum) < parNum)
  355. N[i][1 * yNum] += alpha[1];
  356. }
  357. return;
  358. }
  359. /*----------------------------------------------------------------------------*/
  360. /* Observations estimation */
  361. void obsEstimateBicubic(double **obsV, double *obsE, double *parV,
  362. double deltX, double deltY, int xNm, int yNm,
  363. double xMi, double yMi, int obsN)
  364. {
  365. int i, k, h; /* counters */
  366. double alpha[4][4]; /* coefficients */
  367. int i_x; /* x = (xMin + (i_x * deltaX) + csi_x) */
  368. double csi_x;
  369. int i_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
  370. double csi_y;
  371. for (i = 0; i < obsN; i++) {
  372. obsE[i] = 0;
  373. node_x(obsV[i][0], &i_x, &csi_x, xMi, deltX);
  374. node_y(obsV[i][1], &i_y, &csi_y, yMi, deltY);
  375. if ((i_x >= -2) && (i_x <= xNm) && (i_y >= -2) && (i_y <= yNm)) {
  376. csi_x = csi_x / deltX;
  377. csi_y = csi_y / deltY;
  378. alpha[0][0] = phi_44(1 + csi_x, 1 + csi_y);
  379. alpha[0][1] = phi_43(1 + csi_x, csi_y);
  380. alpha[0][2] = phi_43(1 + csi_x, 1 - csi_y);
  381. alpha[0][3] = phi_44(1 + csi_x, 2 - csi_y);
  382. alpha[1][0] = phi_34(csi_x, 1 + csi_y);
  383. alpha[1][1] = phi_33(csi_x, csi_y);
  384. alpha[1][2] = phi_33(csi_x, 1 - csi_y);
  385. alpha[1][3] = phi_34(csi_x, 2 - csi_y);
  386. alpha[2][0] = phi_34(1 - csi_x, 1 + csi_y);
  387. alpha[2][1] = phi_33(1 - csi_x, csi_y);
  388. alpha[2][2] = phi_33(1 - csi_x, 1 - csi_y);
  389. alpha[2][3] = phi_34(1 - csi_x, 2 - csi_y);
  390. alpha[3][0] = phi_44(2 - csi_x, 1 + csi_y);
  391. alpha[3][1] = phi_43(2 - csi_x, csi_y);
  392. alpha[3][2] = phi_43(2 - csi_x, 1 - csi_y);
  393. alpha[3][3] = phi_44(2 - csi_x, 2 - csi_y);
  394. for (k = -1; k <= 2; k++) {
  395. for (h = -1; h <= 2; h++) {
  396. if (((i_x + k) >= 0) && ((i_x + k) < xNm) &&
  397. ((i_y + h) >= 0) && ((i_y + h) < yNm))
  398. obsE[i] +=
  399. parV[order(i_x + k, i_y + h, yNm)] * alpha[k +
  400. 1][h +
  401. 1];
  402. }
  403. }
  404. }
  405. }
  406. return;
  407. }
  408. /*--------------------------------------------------------------------------------------*/
  409. /* Data interpolation in a generic point */
  410. double dataInterpolateBicubic(double x, double y, double deltaX,
  411. double deltaY, int xNum, int yNum, double xMin,
  412. double yMin, double *parVect)
  413. {
  414. double z; /* abscissa, ordinate and associated value */
  415. int k, h; /* counters */
  416. double alpha[4][4]; /* coefficients */
  417. int i_x, i_y; /* x = (xMin + (i_x * deltaX) + csi_x) */
  418. double csi_x, csi_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
  419. z = 0;
  420. node_x(x, &i_x, &csi_x, xMin, deltaX);
  421. node_y(y, &i_y, &csi_y, yMin, deltaY);
  422. if ((i_x >= -2) && (i_x <= xNum) && (i_y >= -2) && (i_y <= yNum)) {
  423. csi_x = csi_x / deltaX;
  424. csi_y = csi_y / deltaY;
  425. alpha[0][0] = phi_44(1 + csi_x, 1 + csi_y);
  426. alpha[0][1] = phi_43(1 + csi_x, csi_y);
  427. alpha[0][2] = phi_43(1 + csi_x, 1 - csi_y);
  428. alpha[0][3] = phi_44(1 + csi_x, 2 - csi_y);
  429. alpha[1][0] = phi_34(csi_x, 1 + csi_y);
  430. alpha[1][1] = phi_33(csi_x, csi_y);
  431. alpha[1][2] = phi_33(csi_x, 1 - csi_y);
  432. alpha[1][3] = phi_34(csi_x, 2 - csi_y);
  433. alpha[2][0] = phi_34(1 - csi_x, 1 + csi_y);
  434. alpha[2][1] = phi_33(1 - csi_x, csi_y);
  435. alpha[2][2] = phi_33(1 - csi_x, 1 - csi_y);
  436. alpha[2][3] = phi_34(1 - csi_x, 2 - csi_y);
  437. alpha[3][0] = phi_44(2 - csi_x, 1 + csi_y);
  438. alpha[3][1] = phi_43(2 - csi_x, csi_y);
  439. alpha[3][2] = phi_43(2 - csi_x, 1 - csi_y);
  440. alpha[3][3] = phi_44(2 - csi_x, 2 - csi_y);
  441. for (k = -1; k <= 2; k++) {
  442. for (h = -1; h <= 2; h++) {
  443. if (((i_x + k) >= 0) && ((i_x + k) < xNum) && ((i_y + h) >= 0)
  444. && ((i_y + h) < yNum))
  445. z += parVect[order(i_x + k, i_y + h, yNum)] * alpha[k +
  446. 1][h +
  447. 1];
  448. }
  449. }
  450. }
  451. return z;
  452. }
  453. /*----------------------------------------------------------------------------*/
  454. /* Observations estimation */
  455. void obsEstimateBilin(double **obsV, double *obsE, double *parV, double deltX,
  456. double deltY, int xNm, int yNm, double xMi, double yMi,
  457. int obsN)
  458. {
  459. int i, k, h; /* counters */
  460. double alpha[2][2]; /* coefficients */
  461. int i_x; /* x = (xMin + (i_x * deltaX) + csi_x) */
  462. double csi_x;
  463. int i_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
  464. double csi_y;
  465. for (i = 0; i < obsN; i++) {
  466. obsE[i] = 0;
  467. node_x(obsV[i][0], &i_x, &csi_x, xMi, deltX);
  468. node_y(obsV[i][1], &i_y, &csi_y, yMi, deltY);
  469. if ((i_x >= -1) && (i_x < xNm) && (i_y >= -1) && (i_y < yNm)) {
  470. csi_x = csi_x / deltX;
  471. csi_y = csi_y / deltY;
  472. alpha[0][0] = phi(csi_x, csi_y);
  473. alpha[0][1] = phi(csi_x, 1 - csi_y);
  474. alpha[1][0] = phi(1 - csi_x, csi_y);
  475. alpha[1][1] = phi(1 - csi_x, 1 - csi_y);
  476. for (k = 0; k <= 1; k++) {
  477. for (h = 0; h <= 1; h++) {
  478. if (((i_x + k) >= 0) && ((i_x + k) < xNm) &&
  479. ((i_y + h) >= 0) && ((i_y + h) < yNm))
  480. obsE[i] +=
  481. parV[order(i_x + k, i_y + h, yNm)] * alpha[k][h];
  482. }
  483. }
  484. }
  485. }
  486. return;
  487. }
  488. /*--------------------------------------------------------------------------------------*/
  489. /* Data interpolation in a generic point */
  490. double dataInterpolateBilin(double x, double y, double deltaX, double deltaY,
  491. int xNum, int yNum, double xMin, double yMin,
  492. double *parVect)
  493. {
  494. double z; /* abscissa, ordinate and associated value */
  495. int k, h; /* counters */
  496. double alpha[2][2]; /* coefficients */
  497. int i_x, i_y; /* x = (xMin + (i_x * deltaX) + csi_x) */
  498. double csi_x, csi_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
  499. z = 0;
  500. node_x(x, &i_x, &csi_x, xMin, deltaX);
  501. node_y(y, &i_y, &csi_y, yMin, deltaY);
  502. if ((i_x >= -1) && (i_x < xNum) && (i_y >= -1) && (i_y < yNum)) {
  503. csi_x = csi_x / deltaX;
  504. csi_y = csi_y / deltaY;
  505. alpha[0][0] = phi(csi_x, csi_y);
  506. alpha[0][1] = phi(csi_x, 1 - csi_y);
  507. alpha[1][0] = phi(1 - csi_x, csi_y);
  508. alpha[1][1] = phi(1 - csi_x, 1 - csi_y);
  509. for (k = 0; k <= 1; k++) {
  510. for (h = 0; h <= 1; h++) {
  511. if (((i_x + k) >= 0) && ((i_x + k) < xNum) && ((i_y + h) >= 0)
  512. && ((i_y + h) < yNum))
  513. z += parVect[order(i_x + k, i_y + h, yNum)] * alpha[k][h];
  514. }
  515. }
  516. }
  517. return z;
  518. }