123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- /***********************************************************************
- *
- * MODULE: lidarlib
- *
- * AUTHOR(S): Roberto Antolin
- *
- * PURPOSE: LIDAR Spline Interpolation
- *
- * COPYRIGHT: (C) 2006 by Politecnico di Milano -
- * Polo Regionale di Como
- *
- * This program is free software under the
- * GNU General Public License (>=v2).
- * Read the file COPYING that comes with GRASS
- * for details.
- *
- **************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <float.h>
- #include <math.h>
- #include <string.h>
- #include <grass/lidar.h>
- /*----------------------------------------------------------------------------*/
- /* Abscissa node index computation */
- void node_x(double x, int *i_x, double *csi_x, double xMin, double deltaX)
- {
- *i_x = (int)((x - xMin) / deltaX);
- *csi_x = (double)((x - xMin) - (*i_x * deltaX));
- return;
- }
- /*----------------------------------------------------------------------------*/
- /* Ordinate node index computation */
- void node_y(double y, int *i_y, double *csi_y, double yMin, double deltaY)
- {
- *i_y = (int)((y - yMin) / deltaY);
- *csi_y = (double)((y - yMin) - (*i_y * deltaY));
- return;
- }
- /*----------------------------------------------------------------------------*/
- /* Node order computation */
- int order(int i_x, int i_y, int yNum)
- {
- return (i_y + i_x * yNum);
- }
- /*----------------------------------------------------------------------------*/
- /* Design matrix coefficients computation */
- double phi_3(double csi)
- {
- return ((pow(2 - csi, 3.) - pow(1 - csi, 3.) * 4) / 6.);
- }
- double phi_4(double csi)
- {
- return (pow(2 - csi, 3.) / 6.);
- }
- double phi_33(double csi_x, double csi_y)
- {
- return (phi_3(csi_x) * phi_3(csi_y));
- }
- double phi_34(double csi_x, double csi_y)
- {
- return (phi_3(csi_x) * phi_4(csi_y));
- }
- double phi_43(double csi_x, double csi_y)
- {
- return (phi_4(csi_x) * phi_3(csi_y));
- }
- double phi_44(double csi_x, double csi_y)
- {
- return (phi_4(csi_x) * phi_4(csi_y));
- }
- double phi(double csi_x, double csi_y)
- {
- return ((1 - csi_x) * (1 - csi_y));
- }
- /*----------------------------------------------------------------------------*/
- /* Normal system computation for bicubic spline interpolation */
- void normalDefBicubic(double **N, double *TN, double *Q, double **obsVect,
- double deltaX, double deltaY, int xNum, int yNum,
- double xMin, double yMin, int obsNum, int parNum,
- int BW)
- {
- int i, k, h, m, n, n0; /* counters */
- double alpha[4][4]; /* coefficients */
- int i_x; /* x = (xMin + (i_x * deltaX) + csi_x) */
- double csi_x;
- int i_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
- double csi_y;
- /*--------------------------------------*/
- for (k = 0; k < parNum; k++) {
- for (h = 0; h < BW; h++)
- N[k][h] = 0.; /* Normal matrix inizialization */
- TN[k] = 0.; /* Normal vector inizialization */
- }
- /*--------------------------------------*/
- for (i = 0; i < obsNum; i++) {
- node_x(obsVect[i][0], &i_x, &csi_x, xMin, deltaX);
- node_y(obsVect[i][1], &i_y, &csi_y, yMin, deltaY);
- if ((i_x >= -2) && (i_x <= xNum) && (i_y >= -2) && (i_y <= yNum)) {
- csi_x = csi_x / deltaX;
- csi_y = csi_y / deltaY;
- alpha[0][0] = phi_44(1 + csi_x, 1 + csi_y);
- alpha[0][1] = phi_43(1 + csi_x, csi_y);
- alpha[0][2] = phi_43(1 + csi_x, 1 - csi_y);
- alpha[0][3] = phi_44(1 + csi_x, 2 - csi_y);
- alpha[1][0] = phi_34(csi_x, 1 + csi_y);
- alpha[1][1] = phi_33(csi_x, csi_y);
- alpha[1][2] = phi_33(csi_x, 1 - csi_y);
- alpha[1][3] = phi_34(csi_x, 2 - csi_y);
- alpha[2][0] = phi_34(1 - csi_x, 1 + csi_y);
- alpha[2][1] = phi_33(1 - csi_x, csi_y);
- alpha[2][2] = phi_33(1 - csi_x, 1 - csi_y);
- alpha[2][3] = phi_34(1 - csi_x, 2 - csi_y);
- alpha[3][0] = phi_44(2 - csi_x, 1 + csi_y);
- alpha[3][1] = phi_43(2 - csi_x, csi_y);
- alpha[3][2] = phi_43(2 - csi_x, 1 - csi_y);
- alpha[3][3] = phi_44(2 - csi_x, 2 - csi_y);
- for (k = -1; k <= 2; k++) {
- for (h = -1; h <= 2; h++) {
- if (((i_x + k) >= 0) && ((i_x + k) < xNum) &&
- ((i_y + h) >= 0) && ((i_y + h) < yNum)) {
- for (m = k; m <= 2; m++) {
- if (m == k)
- n0 = h;
- else
- n0 = -1;
- for (n = n0; n <= 2; n++) {
- if (((i_x + m) >= 0) && ((i_x + m) < xNum) &&
- ((i_y + n) >= 0) && ((i_y + n) < yNum)) {
- N[order(i_x + k, i_y + h, yNum)][order
- (i_x + m,
- i_y + n,
- yNum) -
- order(i_x
- +
- k,
- i_y
- +
- h,
- yNum)]
- +=
- alpha[k + 1][h +
- 1] * (1 / Q[i]) *
- alpha[m + 1][n + 1];
- /* 1/Q[i] only refers to the variances */
- }
- }
- }
- TN[order(i_x + k, i_y + h, yNum)] +=
- obsVect[i][2] * (1 / Q[i]) * alpha[k + 1][h + 1];
- }
- }
- }
- }
- }
- return;
- }
- /*----------------------------------------------------------------------------*/
- /* Normal system correction - Introduzione della correzione dovuta alle
- pseudosservazioni (Tykonov) - LAPALCIANO - */
- void nCorrectLapl(double **N, double lambda, int xNum, int yNum,
- double deltaX, double deltaY)
- {
- int i_x, i_y; /* counters */
- int k, h, m, n, n0; /* counters */
- double alpha[5][5]; /* coefficients */
- double lambdaX, lambdaY;
- /*--------------------------------------*/
- lambdaX = lambda * (deltaY / deltaX);
- lambdaY = lambda * (deltaX / deltaY);
- alpha[0][0] = 0;
- alpha[0][1] = lambdaX * (1 / 36.); /* There is lambda because Q^(-1) contains 1/(1/lambda) */
- alpha[0][2] = lambdaX * (1 / 9.);
- alpha[0][3] = lambdaX * (1 / 36.);
- alpha[0][4] = 0;
- alpha[1][0] = lambdaY * (1 / 36.);
- alpha[1][1] = lambdaX * (1 / 18.) + lambdaY * (1 / 18.);
- alpha[1][2] = lambdaX * (2 / 9.) - lambdaY * (1 / 6.);
- alpha[1][3] = lambdaX * (1 / 18.) + lambdaY * (1 / 18.);
- alpha[1][4] = lambdaY * (1 / 36.);
- alpha[2][0] = lambdaY * (1 / 9.);
- alpha[2][1] = -lambdaX * (1 / 6.) + lambdaY * (2 / 9.);
- alpha[2][2] = -lambdaX * (2 / 3.) - lambdaY * (2 / 3.);
- alpha[2][3] = -lambdaX * (1 / 6.) + lambdaY * (2 / 9.);
- alpha[2][4] = lambdaY * (1 / 9.);
- alpha[3][0] = lambdaY * (1 / 36.);
- alpha[3][1] = lambdaX * (1 / 18.) + lambdaY * (1 / 18.);
- alpha[3][2] = lambdaX * (2 / 9.) - lambdaY * (1 / 6.);
- alpha[3][3] = lambdaX * (1 / 18.) + lambdaY * (1 / 18.);
- alpha[3][4] = lambdaY * (1 / 36.);
- alpha[4][0] = 0;
- alpha[4][1] = lambdaX * (1 / 36.);
- alpha[4][2] = lambdaX * (1 / 9.);
- alpha[4][3] = lambdaX * (1 / 36.);
- alpha[4][4] = 0;
- for (i_x = 0; i_x < xNum; i_x++) {
- for (i_y = 0; i_y < yNum; i_y++) {
- for (k = -2; k <= 2; k++) {
- for (h = -2; h <= 2; h++) {
- if (((i_x + k) >= 0) && ((i_x + k) < xNum) &&
- ((i_y + h) >= 0) && ((i_y + h) < yNum)) {
- for (m = k; m <= 2; m++) {
- if (m == k)
- n0 = h;
- else
- n0 = -2;
- for (n = n0; n <= 2; n++) {
- if (((i_x + m) >= 0) &&
- ((i_x + m) <= (xNum - 1)) &&
- ((i_y + n) >= 0) &&
- ((i_y + n) <= (yNum - 1))) {
- if ((alpha[k + 2][h + 2] != 0) &&
- (alpha[m + 2][n + 2] != 0)) {
- N[order(i_x + k, i_y + h, yNum)][order
- (i_x
- + m,
- i_y
- + n,
- yNum)
- -
- order
- (i_x
- + k,
- i_y
- + h,
- yNum)]
- +=
- alpha[k + 2][h + 2] * alpha[m +
- 2][n +
- 2];
- }
- }
- }
- }
- }
- }
- }
- }
- }
- return;
- }
- /*----------------------------------------------------------------------------*/
- /* Normal system computation for bilinear spline interpolation */
- void normalDefBilin(double **N, double *TN, double *Q, double **obsVect,
- double deltaX, double deltaY, int xNum, int yNum,
- double xMin, double yMin, int obsNum, int parNum, int BW)
- {
- int i, k, h, m, n, n0; /* counters */
- double alpha[2][2]; /* coefficients */
- int i_x; /* x = (xMin + (i_x * deltaX) + csi_x) */
- double csi_x;
- int i_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
- double csi_y;
- /*--------------------------------------*/
- for (k = 0; k < parNum; k++) {
- for (h = 0; h < BW; h++)
- N[k][h] = 0.; /* Normal matrix inizialization */
- TN[k] = 0.; /* Normal vector inizialization */
- }
- /*--------------------------------------*/
- for (i = 0; i < obsNum; i++) {
- node_x(obsVect[i][0], &i_x, &csi_x, xMin, deltaX);
- node_y(obsVect[i][1], &i_y, &csi_y, yMin, deltaY);
- if ((i_x >= -1) && (i_x < xNum) && (i_y >= -1) && (i_y < yNum)) {
- csi_x = csi_x / deltaX;
- csi_y = csi_y / deltaY;
- alpha[0][0] = phi(csi_x, csi_y);
- alpha[0][1] = phi(csi_x, 1 - csi_y);
- alpha[1][0] = phi(1 - csi_x, csi_y);
- alpha[1][1] = phi(1 - csi_x, 1 - csi_y);
- for (k = 0; k <= 1; k++) {
- for (h = 0; h <= 1; h++) {
- if (((i_x + k) >= 0) && ((i_x + k) <= (xNum - 1)) &&
- ((i_y + h) >= 0) && ((i_y + h) <= (yNum - 1))) {
- for (m = k; m <= 1; m++) {
- if (m == k)
- n0 = h;
- else
- n0 = 0;
- for (n = n0; n <= 1; n++) {
- if (((i_x + m) >= 0) && ((i_x + m) < xNum) &&
- ((i_y + n) >= 0) && ((i_y + n) < yNum)) {
- N[order(i_x + k, i_y + h, yNum)][order
- (i_x + m,
- i_y + n,
- yNum) -
- order(i_x
- +
- k,
- i_y
- +
- h,
- yNum)]
- +=
- alpha[k][h] * (1 / Q[i]) *
- alpha[m][n];
- /* 1/Q[i] only refers to the variances */
- }
- }
- }
- TN[order(i_x + k, i_y + h, yNum)] +=
- obsVect[i][2] * (1 / Q[i]) * alpha[k][h];
- }
- }
- }
- }
- }
- return;
- }
- /*----------------------------------------------------------------------------*/
- /* Normal system correction - Introduzione della correzione dovuta alle
- pseudosservazioni (Tykonov) - GRADIENTE - */
- #ifdef notdef
- void nCorrectGrad(double **N, double lambda, int xNum, int yNum,
- double deltaX, double deltaY)
- {
- int i;
- int parNum;
- double alpha[3];
- double lambdaX, lambdaY;
- lambdaX = lambda * (deltaY / deltaX);
- lambdaY = lambda * (deltaX / deltaY);
- parNum = xNum * yNum;
- alpha[0] = lambdaX / 2. + lambdaY / 2.;
- alpha[1] = -lambdaX / 4.;
- alpha[2] = -lambdaY / 4.;
- for (i = 0; i < parNum; i++) {
- N[i][0] += alpha[0];
- if ((i + 2) < parNum)
- N[i][2] += alpha[2];
- if ((i + 2 * yNum) < parNum)
- N[i][2 * yNum] += alpha[1];
- }
- }
- #endif
- /*1-DELTA discretization */
- void nCorrectGrad(double **N, double lambda, int xNum, int yNum,
- double deltaX, double deltaY)
- {
- int i;
- int parNum;
- double alpha[3];
- double lambdaX, lambdaY;
- lambdaX = lambda * (deltaY / deltaX);
- lambdaY = lambda * (deltaX / deltaY);
- parNum = xNum * yNum;
- alpha[0] = 2 * lambdaX + 2 * lambdaY;
- alpha[1] = -lambdaX;
- alpha[2] = -lambdaY;
- for (i = 0; i < parNum; i++) {
- N[i][0] += alpha[0];
- if ((i + 1) < parNum)
- N[i][1] += alpha[2];
- if ((i + 1 * yNum) < parNum)
- N[i][1 * yNum] += alpha[1];
- }
- return;
- }
- /*----------------------------------------------------------------------------*/
- /* Observations estimation */
- void obsEstimateBicubic(double **obsV, double *obsE, double *parV,
- double deltX, double deltY, int xNm, int yNm,
- double xMi, double yMi, int obsN)
- {
- int i, k, h; /* counters */
- double alpha[4][4]; /* coefficients */
- int i_x; /* x = (xMin + (i_x * deltaX) + csi_x) */
- double csi_x;
- int i_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
- double csi_y;
- for (i = 0; i < obsN; i++) {
- obsE[i] = 0;
- node_x(obsV[i][0], &i_x, &csi_x, xMi, deltX);
- node_y(obsV[i][1], &i_y, &csi_y, yMi, deltY);
- if ((i_x >= -2) && (i_x <= xNm) && (i_y >= -2) && (i_y <= yNm)) {
- csi_x = csi_x / deltX;
- csi_y = csi_y / deltY;
- alpha[0][0] = phi_44(1 + csi_x, 1 + csi_y);
- alpha[0][1] = phi_43(1 + csi_x, csi_y);
- alpha[0][2] = phi_43(1 + csi_x, 1 - csi_y);
- alpha[0][3] = phi_44(1 + csi_x, 2 - csi_y);
- alpha[1][0] = phi_34(csi_x, 1 + csi_y);
- alpha[1][1] = phi_33(csi_x, csi_y);
- alpha[1][2] = phi_33(csi_x, 1 - csi_y);
- alpha[1][3] = phi_34(csi_x, 2 - csi_y);
- alpha[2][0] = phi_34(1 - csi_x, 1 + csi_y);
- alpha[2][1] = phi_33(1 - csi_x, csi_y);
- alpha[2][2] = phi_33(1 - csi_x, 1 - csi_y);
- alpha[2][3] = phi_34(1 - csi_x, 2 - csi_y);
- alpha[3][0] = phi_44(2 - csi_x, 1 + csi_y);
- alpha[3][1] = phi_43(2 - csi_x, csi_y);
- alpha[3][2] = phi_43(2 - csi_x, 1 - csi_y);
- alpha[3][3] = phi_44(2 - csi_x, 2 - csi_y);
- for (k = -1; k <= 2; k++) {
- for (h = -1; h <= 2; h++) {
- if (((i_x + k) >= 0) && ((i_x + k) < xNm) &&
- ((i_y + h) >= 0) && ((i_y + h) < yNm))
- obsE[i] +=
- parV[order(i_x + k, i_y + h, yNm)] * alpha[k +
- 1][h +
- 1];
- }
- }
- }
- }
- return;
- }
- /*--------------------------------------------------------------------------------------*/
- /* Data interpolation in a generic point */
- double dataInterpolateBicubic(double x, double y, double deltaX,
- double deltaY, int xNum, int yNum, double xMin,
- double yMin, double *parVect)
- {
- double z; /* abscissa, ordinate and associated value */
- int k, h; /* counters */
- double alpha[4][4]; /* coefficients */
- int i_x, i_y; /* x = (xMin + (i_x * deltaX) + csi_x) */
- double csi_x, csi_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
- z = 0;
- node_x(x, &i_x, &csi_x, xMin, deltaX);
- node_y(y, &i_y, &csi_y, yMin, deltaY);
- if ((i_x >= -2) && (i_x <= xNum) && (i_y >= -2) && (i_y <= yNum)) {
- csi_x = csi_x / deltaX;
- csi_y = csi_y / deltaY;
- alpha[0][0] = phi_44(1 + csi_x, 1 + csi_y);
- alpha[0][1] = phi_43(1 + csi_x, csi_y);
- alpha[0][2] = phi_43(1 + csi_x, 1 - csi_y);
- alpha[0][3] = phi_44(1 + csi_x, 2 - csi_y);
- alpha[1][0] = phi_34(csi_x, 1 + csi_y);
- alpha[1][1] = phi_33(csi_x, csi_y);
- alpha[1][2] = phi_33(csi_x, 1 - csi_y);
- alpha[1][3] = phi_34(csi_x, 2 - csi_y);
- alpha[2][0] = phi_34(1 - csi_x, 1 + csi_y);
- alpha[2][1] = phi_33(1 - csi_x, csi_y);
- alpha[2][2] = phi_33(1 - csi_x, 1 - csi_y);
- alpha[2][3] = phi_34(1 - csi_x, 2 - csi_y);
- alpha[3][0] = phi_44(2 - csi_x, 1 + csi_y);
- alpha[3][1] = phi_43(2 - csi_x, csi_y);
- alpha[3][2] = phi_43(2 - csi_x, 1 - csi_y);
- alpha[3][3] = phi_44(2 - csi_x, 2 - csi_y);
- for (k = -1; k <= 2; k++) {
- for (h = -1; h <= 2; h++) {
- if (((i_x + k) >= 0) && ((i_x + k) < xNum) && ((i_y + h) >= 0)
- && ((i_y + h) < yNum))
- z += parVect[order(i_x + k, i_y + h, yNum)] * alpha[k +
- 1][h +
- 1];
- }
- }
- }
- return z;
- }
- /*----------------------------------------------------------------------------*/
- /* Observations estimation */
- void obsEstimateBilin(double **obsV, double *obsE, double *parV, double deltX,
- double deltY, int xNm, int yNm, double xMi, double yMi,
- int obsN)
- {
- int i, k, h; /* counters */
- double alpha[2][2]; /* coefficients */
- int i_x; /* x = (xMin + (i_x * deltaX) + csi_x) */
- double csi_x;
- int i_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
- double csi_y;
- for (i = 0; i < obsN; i++) {
- obsE[i] = 0;
- node_x(obsV[i][0], &i_x, &csi_x, xMi, deltX);
- node_y(obsV[i][1], &i_y, &csi_y, yMi, deltY);
- if ((i_x >= -1) && (i_x < xNm) && (i_y >= -1) && (i_y < yNm)) {
- csi_x = csi_x / deltX;
- csi_y = csi_y / deltY;
- alpha[0][0] = phi(csi_x, csi_y);
- alpha[0][1] = phi(csi_x, 1 - csi_y);
- alpha[1][0] = phi(1 - csi_x, csi_y);
- alpha[1][1] = phi(1 - csi_x, 1 - csi_y);
- for (k = 0; k <= 1; k++) {
- for (h = 0; h <= 1; h++) {
- if (((i_x + k) >= 0) && ((i_x + k) < xNm) &&
- ((i_y + h) >= 0) && ((i_y + h) < yNm))
- obsE[i] +=
- parV[order(i_x + k, i_y + h, yNm)] * alpha[k][h];
- }
- }
- }
- }
- return;
- }
- /*--------------------------------------------------------------------------------------*/
- /* Data interpolation in a generic point */
- double dataInterpolateBilin(double x, double y, double deltaX, double deltaY,
- int xNum, int yNum, double xMin, double yMin,
- double *parVect)
- {
- double z; /* abscissa, ordinate and associated value */
- int k, h; /* counters */
- double alpha[2][2]; /* coefficients */
- int i_x, i_y; /* x = (xMin + (i_x * deltaX) + csi_x) */
- double csi_x, csi_y; /* y = (yMin + (i_y * deltaY) + csi_y) */
- z = 0;
- node_x(x, &i_x, &csi_x, xMin, deltaX);
- node_y(y, &i_y, &csi_y, yMin, deltaY);
- if ((i_x >= -1) && (i_x < xNum) && (i_y >= -1) && (i_y < yNum)) {
- csi_x = csi_x / deltaX;
- csi_y = csi_y / deltaY;
- alpha[0][0] = phi(csi_x, csi_y);
- alpha[0][1] = phi(csi_x, 1 - csi_y);
- alpha[1][0] = phi(1 - csi_x, csi_y);
- alpha[1][1] = phi(1 - csi_x, 1 - csi_y);
- for (k = 0; k <= 1; k++) {
- for (h = 0; h <= 1; h++) {
- if (((i_x + k) >= 0) && ((i_x + k) < xNum) && ((i_y + h) >= 0)
- && ((i_y + h) < yNum))
- z += parVect[order(i_x + k, i_y + h, yNum)] * alpha[k][h];
- }
- }
- }
- return z;
- }
|