32 #define M(row, col) m->v[(((row) - 1) * (m->n)) + (col) - 1]
36 #define MUNSOLVABLE -1
49 static int calccoef(
struct Control_Points *,
double **,
double **);
50 static int calcls(
struct Control_Points *,
struct MATRIX *,
double *,
double *,
53 static double tps_base_func(
const double x1,
const double y1,
const double x2,
55 static int solvemat(
struct MATRIX *,
double *,
double *,
double *,
double *);
72 double dist, *pe, *pn;
84 *e = E[0] + e1 * E[1] + n1 * E[2];
85 *n =
N[0] + e1 *
N[1] + n1 *
N[2];
87 for (i = 0, j = 0; i < cp->
count; i++) {
90 dist = tps_base_func(e1, n1, pe[i], pn[i]);
92 *e += E[j + 3] * dist;
93 *n +=
N[j + 3] * dist;
109 double **N12tps,
double **E21tps,
115 double xmax, xmin, ymax, ymin;
118 double sumx, sumy, sumx2, sumy2, sumxy;
119 double SSxx, SSyy, SSxy;
123 for (i = numactive = 0; i < cp->
count; i++) {
131 if (numactive > 100000)
134 xmin = xmax = cp->
e1[0];
135 ymin = ymax = cp->
n1[0];
137 sumx = sumy = sumx2 = sumy2 = sumxy = 0.0;
139 for (i = 0; i < cp->
count; i++) {
144 xmax =
MAX(xmax, xx);
145 xmin =
MIN(xmin, xx);
146 ymax =
MAX(ymax, yy);
147 ymin =
MIN(ymin, yy);
160 SSxx = sumx2 - sumx * sumx / numactive;
161 SSyy = sumy2 - sumy * sumy / numactive;
162 SSxy = sumxy - sumx * sumy / numactive;
164 if (delx < 0.001 * dely || dely < 0.001 * delx ||
165 fabs(SSxy * SSxy / (SSxx * SSyy)) > 0.99) {
170 xmin = xmax = cp->
e2[0];
171 ymin = ymax = cp->
n2[0];
173 sumx = sumy = sumx2 = sumy2 = sumxy = 0.0;
174 for (i = 0; i < cp->
count; i++) {
179 xmax =
MAX(xmax, xx);
180 xmin =
MIN(xmin, xx);
181 ymax =
MAX(ymax, yy);
182 ymin =
MIN(ymin, yy);
195 SSxx = sumx2 - sumx * sumx / numactive;
196 SSyy = sumy2 - sumy * sumy / numactive;
197 SSxy = sumxy - sumx * sumy / numactive;
199 if (delx < 0.001 * dely || dely < 0.001 * delx ||
200 fabs(SSxy * SSxy / (SSxx * SSyy)) > 0.99) {
207 G_message(
_(
"Calculating forward transformation coefficients"));
208 status = calccoef(cp, E12tps, N12tps);
224 G_message(
_(
"Calculating backward transformation coefficients"));
225 status = calccoef(cp, E21tps, N21tps);
256 for (i = numactive = 0; i < cp->
count; i++) {
265 m.v =
G_calloc(m.n * m.n,
sizeof(
double));
268 "I_compute_georef_equations_tps()");
272 "I_compute_georef_equations_tps()");
276 "I_compute_georef_equations_tps()");
282 "I_compute_georef_equations_tps()");
286 "I_compute_georef_equations_tps()");
288 status = calcls(cp, &m, a,
b, *E, *
N);
305 static int calcls(
struct Control_Points *cp,
struct MATRIX *m,
double a[],
306 double b[],
double E[],
310 int i, j, n, o, numactive = 0;
316 for (i = 1; i <= m->n; i++) {
317 for (j = i; j <= m->n; j++) {
322 a[i - 1] =
b[i - 1] = 0.0;
328 for (n = 0; n < cp->
count; n++) {
331 a[numactive + 3] = cp->
e2[n];
332 b[numactive + 3] = cp->
n2[n];
335 M(1, numactive + 3) = 1.0;
336 M(2, numactive + 3) = cp->
e1[n];
337 M(3, numactive + 3) = cp->
n1[n];
339 M(numactive + 3, 1) = 1.0;
340 M(numactive + 3, 2) = cp->
e1[n];
341 M(numactive + 3, 3) = cp->
n1[n];
345 if (numactive < m->n - 3)
349 for (n = 0; n < cp->
count; n++) {
354 for (o = 0; o <= n; o++) {
357 M(i + 3, j + 3) = tps_base_func(cp->
e1[n], cp->
n1[n],
358 cp->
e1[o], cp->
n1[o]);
361 M(j + 3, i + 3) =
M(i + 3, j + 3);
377 return solvemat(m, a,
b, E,
N);
399 static int solvemat(
struct MATRIX *m,
double a[],
double b[],
double E[],
402 int i, j, i2, j2, imark;
406 for (i = 1; i <= m->n; i++) {
414 for (i2 = i + 1; i2 <= m->n; i2++) {
415 temp = fabs(
M(i2, j));
416 if (temp > fabs(pivot)) {
432 for (j2 = 1; j2 <= m->n; j2++) {
434 M(imark, j2) =
M(i, j2);
439 a[imark - 1] = a[i - 1];
443 b[imark - 1] =
b[i - 1];
450 for (i2 = 1; i2 <= m->n; i2++) {
452 factor =
M(i2, j) / pivot;
453 for (j2 = j; j2 <= m->n; j2++)
454 M(i2, j2) -= factor *
M(i, j2);
455 a[i2 - 1] -= factor * a[i - 1];
456 b[i2 - 1] -= factor *
b[i - 1];
465 for (i = 1; i <= m->n; i++) {
466 E[i - 1] = a[i - 1] /
M(i, i);
467 N[i - 1] =
b[i - 1] /
M(i, i);
473 static double tps_base_func(
const double x1,
const double y1,
const double x2,
479 if ((x1 == x2) && (y1 == y2))
482 dist = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
484 return dist * log(dist) * 0.5;
void G_percent(long, long, int)
Print percent complete messages.
void G_free(void *)
Free allocated memory.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_message(const char *,...) __attribute__((format(printf
int I_georef_tps(double e1, double n1, double *e, double *n, double *E, double *N, struct Control_Points *cp, int fwd)
int I_compute_georef_equations_tps(struct Control_Points *cp, double **E12tps, double **N12tps, double **E21tps, double **N21tps)