PageRenderTime 51ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/v5_6_1/lib/csa/csa.c

#
C | 2077 lines | 1570 code | 299 blank | 208 comment | 412 complexity | 4bde2291933f1df8830c38bfca04656e MD5 | raw file
Possible License(s): LGPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, Apache-2.0, GPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. /******************************************************************************
  2. *
  3. * File: csa.c
  4. *
  5. * Created: 16/10/2002
  6. *
  7. * Author: Pavel Sakov
  8. * CSIRO Marine Research
  9. *
  10. * Purpose: 2D data approximation with bivariate C1 cubic spline.
  11. * A set of library functions + standalone utility.
  12. *
  13. * Description: See J. Haber, F. Zeilfelder, O.Davydov and H.-P. Seidel,
  14. * Smooth approximation and rendering of large scattered data
  15. * sets, in ``Proceedings of IEEE Visualization 2001''
  16. * (Th.Ertl, K.Joy and A.Varshney, Eds.), pp.341-347, 571,
  17. * IEEE Computer Society, 2001.
  18. * http://www.uni-giessen.de/www-Numerische-Mathematik/
  19. * davydov/VIS2001.ps.gz
  20. * http://www.math.uni-mannheim.de/~lsmath4/paper/
  21. * VIS2001.pdf.gz
  22. *
  23. * Revisions: 09/04/2003 PS: Modified points_read() to read from a
  24. * file specified by name, not by handle.
  25. *
  26. *****************************************************************************/
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <stdarg.h>
  30. #include <limits.h>
  31. #include <float.h>
  32. #include <math.h>
  33. #include <assert.h>
  34. #include <string.h>
  35. #include <errno.h>
  36. #include "version.h"
  37. #include "nan.h"
  38. #include "csa.h"
  39. int csa_verbose = 0;
  40. #define NPASTART 5 /* Number of Points Allocated at Start */
  41. #define SVD_NMAX 30 /* Maximal number of iterations in svd() */
  42. /* default algorithm parameters */
  43. #define NPMIN_DEF 3
  44. #define NPMAX_DEF 40
  45. #define K_DEF 140
  46. #define NPPC_DEF 5
  47. struct square;
  48. typedef struct square square;
  49. typedef struct {
  50. square* parent;
  51. int index; /* index within parent square; 0 <= index <=
  52. * 3 */
  53. point vertices[3];
  54. point middle; /* barycenter */
  55. double h; /* parent square edge length */
  56. double r; /* data visibility radius */
  57. /*
  58. * points used -- in primary triangles only
  59. */
  60. int nallocated;
  61. int npoints;
  62. point** points;
  63. int primary; /* flag -- whether calculate spline
  64. * coefficients directly (by least squares
  65. * method) (primary = 1) or indirectly (from
  66. * C1 smoothness conditions) (primary = 0) */
  67. int hascoeffs; /* flag -- whether there are no NaNs among
  68. * the spline coefficients */
  69. int order; /* spline order -- for primary triangles only
  70. */
  71. } triangle;
  72. struct square {
  73. csa* parent;
  74. int i, j; /* indices */
  75. int nallocated;
  76. int npoints;
  77. point** points;
  78. int primary; /* flag -- whether this square contains a
  79. * primary triangle */
  80. triangle* triangles[4];
  81. double coeffs[25];
  82. };
  83. struct csa {
  84. double xmin;
  85. double xmax;
  86. double ymin;
  87. double ymax;
  88. int nallocated;
  89. int npoints;
  90. point** points;
  91. /*
  92. * squarization
  93. */
  94. int ni;
  95. int nj;
  96. double h;
  97. square*** squares; /* square* [j][i] */
  98. int npt; /* Number of Primary Triangles */
  99. triangle** pt; /* Primary Triangles -- triangle* [npt] */
  100. /*
  101. * algorithm parameters
  102. */
  103. int npmin; /* minimal number of points locally involved
  104. * in * spline calculation (normally = 3) */
  105. int npmax; /* maximal number of points locally involved
  106. * in * spline calculation (required > 10, *
  107. * recommended 20 < npmax < 60) */
  108. double k; /* relative tolerance multiple in fitting
  109. * spline coefficients: the higher this
  110. * value, the higher degree of the locally
  111. * fitted spline (recommended 80 < k < 200) */
  112. int nppc; /* average number of points per square */
  113. };
  114. static void csa_quit(char* format, ...)
  115. {
  116. va_list args;
  117. fflush(stdout); /* just in case -- to have the exit message
  118. * last */
  119. fprintf(stderr, "error: csa: ");
  120. va_start(args, format);
  121. vfprintf(stderr, format, args);
  122. va_end(args);
  123. exit(1);
  124. }
  125. /* Allocates n1xn2 matrix of something. Note that it will be accessed as
  126. * [n2][n1].
  127. * @param n1 Number of columns
  128. * @param n2 Number of rows
  129. * @return Matrix
  130. */
  131. static void* alloc2d(int n1, int n2, size_t unitsize)
  132. {
  133. unsigned int size;
  134. char* p;
  135. char** pp;
  136. int i;
  137. assert(n1 > 0);
  138. assert(n2 > 0);
  139. assert((double) n1 * (double) n2 <= (double) UINT_MAX);
  140. size = n1 * n2;
  141. if ((p = calloc(size, unitsize)) == NULL)
  142. csa_quit("alloc2d(): %s\n", strerror(errno));
  143. assert((double) n2 * (double) sizeof(void*) <= (double) UINT_MAX);
  144. size = n2 * sizeof(void*);
  145. if ((pp = malloc(size)) == NULL)
  146. csa_quit("alloc2d(): %s\n", strerror(errno));
  147. for (i = 0; i < n2; i++)
  148. pp[i] = &p[i * n1 * unitsize];
  149. return pp;
  150. }
  151. /* Destroys n1xn2 matrix.
  152. * @param pp Matrix
  153. */
  154. static void free2d(void* pp)
  155. {
  156. void* p;
  157. assert(pp != NULL);
  158. p = ((void**) pp)[0];
  159. free(pp);
  160. assert(p != NULL);
  161. free(p);
  162. }
  163. static triangle* triangle_create(square* s, point vertices[], int index)
  164. {
  165. triangle* t = malloc(sizeof(triangle));
  166. t->parent = s;
  167. memcpy(t->vertices, vertices, sizeof(point) * 3);
  168. t->middle.x = (vertices[0].x + vertices[1].x + vertices[2].x) / 3.0;
  169. t->middle.y = (vertices[0].y + vertices[1].y + vertices[2].y) / 3.0;
  170. t->h = s->parent->h;
  171. t->index = index;
  172. t->r = 0.0;
  173. t->points = 0;
  174. t->nallocated = 0;
  175. t->npoints = 0;
  176. t->hascoeffs = 0;
  177. t->primary = 0;
  178. t->order = -1;
  179. return t;
  180. }
  181. static void triangle_addpoint(triangle* t, point* p)
  182. {
  183. if (t->nallocated == t->npoints) {
  184. if (t->nallocated == 0) {
  185. t->points = malloc(NPASTART * sizeof(point*));
  186. t->nallocated = NPASTART;
  187. } else {
  188. t->points = realloc(t->points, t->nallocated * 2 * sizeof(point*));
  189. t->nallocated *= 2;
  190. }
  191. }
  192. t->points[t->npoints] = p;
  193. t->npoints++;
  194. }
  195. static void triangle_destroy(triangle* t)
  196. {
  197. if (t->points != NULL)
  198. free(t->points);
  199. free(t);
  200. }
  201. /* Calculates barycentric coordinates of a point.
  202. * Takes into account that possible triangles are rectangular, with the right
  203. * angle at t->vertices[0], the vertices[1] vertex being in
  204. * (-3*PI/4) + (PI/2) * t->index direction from vertices[0], and
  205. * vertices[2] being at (-5*PI/4) + (PI/2) * t->index.
  206. */
  207. static void triangle_calculatebc(triangle* t, point* p, double bc[])
  208. {
  209. double dx = p->x - t->vertices[0].x;
  210. double dy = p->y - t->vertices[0].y;
  211. if (t->index == 0) {
  212. bc[1] = (dy - dx) / t->h;
  213. bc[2] = -(dx + dy) / t->h;
  214. } else if (t->index == 1) {
  215. bc[1] = (dx + dy) / t->h;
  216. bc[2] = (dy - dx) / t->h;
  217. } else if (t->index == 2) {
  218. bc[1] = (dx - dy) / t->h;
  219. bc[2] = (dx + dy) / t->h;
  220. } else {
  221. bc[1] = -(dx + dy) / t->h;
  222. bc[2] = (dx - dy) / t->h;
  223. }
  224. bc[0] = 1.0 - bc[1] - bc[2];
  225. }
  226. static square* square_create(csa* parent, double xmin, double ymin, int i, int j)
  227. {
  228. int ii;
  229. square* s = malloc(sizeof(square));
  230. double h = parent->h;
  231. s->parent = parent;
  232. s->i = i;
  233. s->j = j;
  234. s->points = NULL;
  235. s->nallocated = 0;
  236. s->npoints = 0;
  237. s->primary = 0;
  238. /*
  239. * create 4 triangles formed by diagonals
  240. */
  241. for (ii = 0; ii < 4; ++ii) {
  242. point vertices[3];
  243. vertices[0].x = xmin + h / 2.0;
  244. vertices[0].y = ymin + h / 2.0;
  245. vertices[1].x = xmin + h * (((ii + 1) % 4) / 2); /* 0 1 1 0 */
  246. vertices[1].y = ymin + h * (((ii + 2) % 4) / 2); /* 1 1 0 0 */
  247. vertices[2].x = xmin + h * (ii / 2); /* 0 0 1 1 */
  248. vertices[2].y = ymin + h * (((ii + 1) % 4) / 2); /* 0 1 1 0 */
  249. s->triangles[ii] = triangle_create(s, vertices, ii);
  250. }
  251. for (ii = 0; ii < 25; ++ii)
  252. s->coeffs[ii] = NaN;
  253. return s;
  254. }
  255. static void square_destroy(square* s)
  256. {
  257. int i;
  258. for (i = 0; i < 4; ++i)
  259. triangle_destroy(s->triangles[i]);
  260. if (s->points != NULL)
  261. free(s->points);
  262. free(s);
  263. }
  264. static void square_addpoint(square* s, point* p)
  265. {
  266. if (s->nallocated == s->npoints) {
  267. if (s->nallocated == 0) {
  268. s->points = malloc(NPASTART * sizeof(point*));
  269. s->nallocated = NPASTART;
  270. } else {
  271. s->points = realloc(s->points, s->nallocated * 2 * sizeof(point*));
  272. s->nallocated *= 2;
  273. }
  274. }
  275. s->points[s->npoints] = p;
  276. s->npoints++;
  277. }
  278. csa* csa_create()
  279. {
  280. csa* a = malloc(sizeof(csa));
  281. a->xmin = DBL_MAX;
  282. a->xmax = -DBL_MAX;
  283. a->ymin = DBL_MAX;
  284. a->ymax = -DBL_MAX;
  285. a->points = malloc(NPASTART * sizeof(point*));
  286. a->nallocated = NPASTART;
  287. a->npoints = 0;
  288. a->ni = 0;
  289. a->nj = 0;
  290. a->h = NaN;
  291. a->squares = NULL;
  292. a->npt = 0;
  293. a->pt = NULL;
  294. a->npmin = NPMIN_DEF;
  295. a->npmax = NPMAX_DEF;
  296. a->k = K_DEF;
  297. a->nppc = NPPC_DEF;
  298. return a;
  299. }
  300. void csa_destroy(csa* a)
  301. {
  302. int i, j;
  303. if (a->squares != NULL) {
  304. for (j = 0; j < a->nj; ++j)
  305. for (i = 0; i < a->ni; ++i)
  306. square_destroy(a->squares[j][i]);
  307. free2d(a->squares);
  308. }
  309. if (a->pt != NULL)
  310. free(a->pt);
  311. if (a->points != NULL)
  312. free(a->points);
  313. free(a);
  314. }
  315. void csa_addpoints(csa* a, int n, point points[])
  316. {
  317. int na = a->nallocated;
  318. int i;
  319. assert(a->squares == NULL);
  320. /*
  321. * (can be called prior to squarization only)
  322. */
  323. while (na < a->npoints + n)
  324. na *= 2;
  325. if (na != a->nallocated) {
  326. a->points = realloc(a->points, na * sizeof(point*));
  327. a->nallocated = na;
  328. }
  329. for (i = 0; i < n; ++i) {
  330. point* p = &points[i];
  331. a->points[a->npoints] = p;
  332. a->npoints++;
  333. if (p->x < a->xmin)
  334. a->xmin = p->x;
  335. if (p->x > a->xmax)
  336. a->xmax = p->x;
  337. if (p->y < a->ymin)
  338. a->ymin = p->y;
  339. if (p->y > a->ymax)
  340. a->ymax = p->y;
  341. }
  342. }
  343. /* Marks the squares containing "primary" triangles by setting "primary" flag
  344. * to 1.
  345. */
  346. static void csa_setprimaryflag(csa* a)
  347. {
  348. square*** squares = a->squares;
  349. int nj1 = a->nj - 1;
  350. int ni1 = a->ni - 1;
  351. int i, j;
  352. for (j = 1; j < nj1; ++j) {
  353. for (i = 1; i < ni1; ++i) {
  354. if (squares[j][i]->npoints > 0) {
  355. if ((i + j) % 2 == 0) {
  356. squares[j][i]->primary = 1;
  357. squares[j - 1][i - 1]->primary = 1;
  358. squares[j + 1][i - 1]->primary = 1;
  359. squares[j - 1][i + 1]->primary = 1;
  360. squares[j + 1][i + 1]->primary = 1;
  361. } else {
  362. squares[j - 1][i]->primary = 1;
  363. squares[j + 1][i]->primary = 1;
  364. squares[j][i - 1]->primary = 1;
  365. squares[j][i + 1]->primary = 1;
  366. }
  367. }
  368. }
  369. }
  370. }
  371. /* Splits the data domain in a number of squares.
  372. */
  373. static void csa_squarize(csa* a)
  374. {
  375. int nps[7] = { 0, 0, 0, 0, 0, 0 }; /* stats on number of points per
  376. * square */
  377. double dx = a->xmax - a->xmin;
  378. double dy = a->ymax - a->ymin;
  379. int npoints = a->npoints;
  380. double h;
  381. int i, j, ii, nadj;
  382. if (csa_verbose) {
  383. fprintf(stderr, "squarizing csa:\n");
  384. fflush(stderr);
  385. }
  386. assert(a->squares == NULL);
  387. /*
  388. * (can be done only once)
  389. */
  390. h = sqrt(dx * dy * a->nppc / npoints); /* square edge size */
  391. if (dx < h)
  392. h = dy * a->nppc / npoints;
  393. if (dy < h)
  394. h = dx * a->nppc / npoints;
  395. a->h = h;
  396. a->ni = ceil(dx / h) + 2;
  397. a->nj = ceil(dy / h) + 2;
  398. if (csa_verbose) {
  399. fprintf(stderr, " %d x %d squares\n", a->ni, a->nj);
  400. fflush(stderr);
  401. }
  402. /*
  403. * create squares
  404. */
  405. a->squares = alloc2d(a->ni, a->nj, sizeof(void*));
  406. for (j = 0; j < a->nj; ++j)
  407. for (i = 0; i < a->ni; ++i)
  408. a->squares[j][i] = square_create(a, a->xmin + h * (i - 1), a->ymin + h * (j - 1), i, j);
  409. /*
  410. * map points to squares
  411. */
  412. for (ii = 0; ii < npoints; ++ii) {
  413. point* p = a->points[ii];
  414. i = floor((p->x - a->xmin) / h) + 1;
  415. j = floor((p->y - a->ymin) / h) + 1;
  416. square_addpoint(a->squares[j][i], p);
  417. }
  418. /*
  419. * mark relevant squares with no points
  420. */
  421. csa_setprimaryflag(a);
  422. /*
  423. * Create a list of "primary" triangles, for which spline coefficients
  424. * will be calculated directy (by least squares method), without using
  425. * C1 smoothness conditions.
  426. */
  427. a->pt = malloc((a->ni / 2 + 1) * a->nj * sizeof(triangle*));
  428. for (j = 0, ii = 0, nadj = 0; j < a->nj; ++j) {
  429. for (i = 0; i < a->ni; ++i) {
  430. square* s = a->squares[j][i];
  431. if (s->npoints > 0) {
  432. int nn = s->npoints / 5;
  433. if (nn > 6)
  434. nn = 6;
  435. nps[nn]++;
  436. ii++;
  437. }
  438. if (s->primary && s->npoints == 0)
  439. nadj++;
  440. if (s->primary) {
  441. a->pt[a->npt] = s->triangles[0];
  442. s->triangles[0]->primary = 1;
  443. a->npt++;
  444. }
  445. }
  446. }
  447. if (csa_verbose) {
  448. fprintf(stderr, " %d non-empty squares\n", ii);
  449. fprintf(stderr, " %d primary squares\n", a->npt);
  450. fprintf(stderr, " %d primary squares with no data\n", nadj);
  451. fprintf(stderr, " %.2f points per square \n", (double) a->npoints / ii);
  452. }
  453. if (csa_verbose == 2) {
  454. for (i = 0; i < 6; ++i)
  455. fprintf(stderr, " %d-%d points -- %d squares\n", i * 5, i * 5 + 4, nps[i]);
  456. fprintf(stderr, " %d or more points -- %d squares\n", i * 5, nps[i]);
  457. }
  458. if (csa_verbose == 2) {
  459. fprintf(stderr, " j\\i");
  460. for (i = 0; i < a->ni; ++i)
  461. fprintf(stderr, "%3d ", i);
  462. fprintf(stderr, "\n");
  463. for (j = a->nj - 1; j >= 0; --j) {
  464. fprintf(stderr, "%3d ", j);
  465. for (i = 0; i < a->ni; ++i) {
  466. square* s = a->squares[j][i];
  467. if (s->npoints > 0)
  468. fprintf(stderr, "%3d ", s->npoints);
  469. else
  470. fprintf(stderr, " . ");
  471. }
  472. fprintf(stderr, "\n");
  473. }
  474. }
  475. if (csa_verbose)
  476. fflush(stderr);
  477. }
  478. /* Returns all squares intersecting with a square with center in t->middle
  479. * and edges of length 2*t->r parallel to X and Y axes.
  480. */
  481. static void getsquares(csa* a, triangle* t, int* n, square*** squares)
  482. {
  483. int imin = floor((t->middle.x - t->r - a->xmin) / t->h);
  484. int imax = ceil((t->middle.x + t->r - a->xmin) / t->h);
  485. int jmin = floor((t->middle.y - t->r - a->ymin) / t->h);
  486. int jmax = ceil((t->middle.y + t->r - a->ymin) / t->h);
  487. int i, j;
  488. if (imin < 0)
  489. imin = 0;
  490. if (imax >= a->ni)
  491. imax = a->ni - 1;
  492. if (jmin < 0)
  493. jmin = 0;
  494. if (jmax >= a->nj)
  495. jmax = a->nj - 1;
  496. *n = 0;
  497. (*squares) = malloc((imax - imin + 1) * (jmax - jmin + 1) * sizeof(square*));
  498. for (j = jmin; j <= jmax; ++j) {
  499. for (i = imin; i <= imax; ++i) {
  500. square* s = a->squares[j][i];
  501. if (s->npoints > 0) {
  502. (*squares)[*n] = a->squares[j][i];
  503. (*n)++;
  504. }
  505. }
  506. }
  507. }
  508. static double distance(point* p1, point* p2)
  509. {
  510. return hypot(p1->x - p2->x, p1->y - p2->y);
  511. }
  512. /* Thins data by creating an auxiliary regular grid and for leaving only
  513. * the most central point within each grid cell.
  514. * (I follow the paper here. It is possible that taking average -- in terms of
  515. * both value and position -- of all points within a cell would be a bit more
  516. * robust. However, because of keeping only shallow copies of input points,
  517. * this would require quite a bit of structural changes. So, leaving it as is
  518. * for now.)
  519. */
  520. static void thindata(triangle* t, int npmax)
  521. {
  522. csa* a = t->parent->parent;
  523. int imax = ceil(sqrt((double) (npmax * 3 / 2)));
  524. square*** squares = alloc2d(imax, imax, sizeof(void*));
  525. double h = t->r * 2.0 / imax;
  526. double h2 = h / 2.0;
  527. double xmin = t->middle.x - t->r;
  528. double ymin = t->middle.y - t->r;
  529. int i, j, ii;
  530. for (j = 0; j < imax; ++j)
  531. for (i = 0; i < imax; ++i)
  532. squares[j][i] = square_create(a, xmin + h * i, ymin + h * j, i, j);
  533. for (ii = 0; ii < t->npoints; ++ii) {
  534. point* p = t->points[ii];
  535. int i = floor((p->x - xmin) / h);
  536. int j = floor((p->y - ymin) / h);
  537. square* s = squares[j][i];
  538. if (s->npoints == 0)
  539. square_addpoint(s, p);
  540. else { /* npoints == 1 */
  541. point pmiddle;
  542. pmiddle.x = xmin + h * i + h2;
  543. pmiddle.y = ymin + h * j + h2;
  544. if (distance(s->points[0], &pmiddle) > distance(p, &pmiddle))
  545. s->points[0] = p;
  546. }
  547. }
  548. t->npoints = 0;
  549. for (j = 0; j < imax; ++j) {
  550. for (i = 0; i < imax; ++i) {
  551. square* s = squares[j][i];
  552. if (squares[j][i]->npoints != 0)
  553. triangle_addpoint(t, s->points[0]);
  554. square_destroy(s);
  555. }
  556. }
  557. free2d(squares);
  558. imax++;
  559. }
  560. /* Finds data points to be used in calculating spline coefficients for each
  561. * primary triangle.
  562. */
  563. static void csa_attachpoints(csa* a)
  564. {
  565. int npmin = a->npmin;
  566. int npmax = a->npmax;
  567. int nincreased = 0;
  568. int nthinned = 0;
  569. int i;
  570. assert(a->npt > 0);
  571. if (csa_verbose) {
  572. fprintf(stderr, "pre-processing data points:\n ");
  573. fflush(stderr);
  574. }
  575. for (i = 0; i < a->npt; ++i) {
  576. triangle* t = a->pt[i];
  577. int increased = 0;
  578. if (csa_verbose) {
  579. fprintf(stderr, ".");
  580. fflush(stderr);
  581. }
  582. t->r = t->h * 1.25;
  583. while (1) {
  584. int nsquares = 0;
  585. square** squares = NULL;
  586. int ii;
  587. getsquares(a, t, &nsquares, &squares);
  588. for (ii = 0; ii < nsquares; ++ii) {
  589. square* s = squares[ii];
  590. int iii;
  591. for (iii = 0; iii < s->npoints; ++iii) {
  592. point* p = s->points[iii];
  593. if (distance(p, &t->middle) <= t->r)
  594. triangle_addpoint(t, p);
  595. }
  596. }
  597. free(squares);
  598. if (t->npoints < npmin) {
  599. if (!increased) {
  600. increased = 1;
  601. nincreased++;
  602. }
  603. t->r *= 1.25;
  604. t->npoints = 0;
  605. } else if (t->npoints > npmax) {
  606. nthinned++;
  607. thindata(t, npmax);
  608. if (t->npoints > npmin)
  609. break;
  610. else {
  611. /*
  612. * Sometimes you have too much data, you thin it and --
  613. * oops -- you have too little. This is not a frequent
  614. * event, so let us not bother to put a new subdivision.
  615. */
  616. t->r *= 1.25;
  617. t->npoints = 0;
  618. }
  619. } else
  620. break;
  621. }
  622. }
  623. if (csa_verbose) {
  624. fprintf(stderr, "\n %d sets enhanced, %d sets thinned\n", nincreased, nthinned);
  625. fflush(stderr);
  626. }
  627. }
  628. static int n2q(int n)
  629. {
  630. assert(n >= 3);
  631. if (n >= 10)
  632. return 3;
  633. else if (n >= 6)
  634. return 2;
  635. else /* n == 3 */
  636. return 1;
  637. }
  638. /** Singular value decomposition.
  639. * Borrowed from EISPACK (1972-1973).
  640. * Presents input matrix A as A = U.W.V'.
  641. *
  642. * @param a Input matrix A = U.W[0..m-1][0..n-1]; output matrix U
  643. * @param n Number of columns
  644. * @param m Number of rows
  645. * @param w Ouput vector that presents diagonal matrix W
  646. * @param V output matrix V
  647. */
  648. static void svd(double** a, int n, int m, double* w, double** v)
  649. {
  650. double* rv1;
  651. int i, j, k, l = -1;
  652. double tst1, c, f, g, h, s, scale;
  653. assert(m > 0 && n > 0);
  654. rv1 = malloc(n * sizeof(double));
  655. /*
  656. * householder reduction to bidiagonal form
  657. */
  658. g = 0.0;
  659. scale = 0.0;
  660. tst1 = 0.0;
  661. for (i = 0; i < n; i++) {
  662. l = i + 1;
  663. rv1[i] = scale * g;
  664. g = 0.0;
  665. s = 0.0;
  666. scale = 0.0;
  667. if (i < m) {
  668. for (k = i; k < m; k++)
  669. scale += fabs(a[k][i]);
  670. if (scale != 0.0) {
  671. for (k = i; k < m; k++) {
  672. a[k][i] /= scale;
  673. s += a[k][i] * a[k][i];
  674. }
  675. f = a[i][i];
  676. g = -copysign(sqrt(s), f);
  677. h = f * g - s;
  678. a[i][i] = f - g;
  679. if (i < n - 1) {
  680. for (j = l; j < n; j++) {
  681. s = 0.0;
  682. for (k = i; k < m; k++)
  683. s += a[k][i] * a[k][j];
  684. f = s / h;
  685. for (k = i; k < m; k++)
  686. a[k][j] += f * a[k][i];
  687. }
  688. }
  689. for (k = i; k < m; k++)
  690. a[k][i] *= scale;
  691. }
  692. }
  693. w[i] = scale * g;
  694. g = 0.0;
  695. s = 0.0;
  696. scale = 0.0;
  697. if (i < m && i < n - 1) {
  698. for (k = l; k < n; k++)
  699. scale += fabs(a[i][k]);
  700. if (scale != 0.0) {
  701. for (k = l; k < n; k++) {
  702. a[i][k] /= scale;
  703. s += a[i][k] * a[i][k];
  704. }
  705. f = a[i][l];
  706. g = -copysign(sqrt(s), f);
  707. h = f * g - s;
  708. a[i][l] = f - g;
  709. for (k = l; k < n; k++)
  710. rv1[k] = a[i][k] / h;
  711. for (j = l; j < m; j++) {
  712. s = 0.0;
  713. for (k = l; k < n; k++)
  714. s += a[j][k] * a[i][k];
  715. for (k = l; k < n; k++)
  716. a[j][k] += s * rv1[k];
  717. }
  718. for (k = l; k < n; k++)
  719. a[i][k] *= scale;
  720. }
  721. }
  722. {
  723. double tmp = fabs(w[i]) + fabs(rv1[i]);
  724. tst1 = (tst1 > tmp) ? tst1 : tmp;
  725. }
  726. }
  727. /*
  728. * accumulation of right-hand transformations
  729. */
  730. for (i = n - 1; i >= 0; i--) {
  731. if (i < n - 1) {
  732. if (g != 0.0) {
  733. for (j = l; j < n; j++)
  734. /*
  735. * double division avoids possible underflow
  736. */
  737. v[j][i] = (a[i][j] / a[i][l]) / g;
  738. for (j = l; j < n; j++) {
  739. s = 0.0;
  740. for (k = l; k < n; k++)
  741. s += a[i][k] * v[k][j];
  742. for (k = l; k < n; k++)
  743. v[k][j] += s * v[k][i];
  744. }
  745. }
  746. for (j = l; j < n; j++) {
  747. v[i][j] = 0.0;
  748. v[j][i] = 0.0;
  749. }
  750. }
  751. v[i][i] = 1.0;
  752. g = rv1[i];
  753. l = i;
  754. }
  755. /*
  756. * accumulation of left-hand transformations
  757. */
  758. for (i = (m < n) ? m - 1 : n - 1; i >= 0; i--) {
  759. l = i + 1;
  760. g = w[i];
  761. if (i != n - 1)
  762. for (j = l; j < n; j++)
  763. a[i][j] = 0.0;
  764. if (g != 0.0) {
  765. for (j = l; j < n; j++) {
  766. s = 0.0;
  767. for (k = l; k < m; k++)
  768. s += a[k][i] * a[k][j];
  769. /*
  770. * double division avoids possible underflow
  771. */
  772. f = (s / a[i][i]) / g;
  773. for (k = i; k < m; k++)
  774. a[k][j] += f * a[k][i];
  775. }
  776. for (j = i; j < m; j++)
  777. a[j][i] /= g;
  778. } else
  779. for (j = i; j < m; j++)
  780. a[j][i] = 0.0;
  781. a[i][i] += 1.0;
  782. }
  783. /*
  784. * diagonalization of the bidiagonal form
  785. */
  786. for (k = n - 1; k >= 0; k--) {
  787. int k1 = k - 1;
  788. int its = 0;
  789. while (1) {
  790. int docancellation = 1;
  791. double x, y, z;
  792. int l1 = -1;
  793. its++;
  794. if (its > SVD_NMAX)
  795. csa_quit("svd(): no convergence in %d iterations", SVD_NMAX);
  796. for (l = k; l >= 0; l--) { /* test for splitting */
  797. double tst2 = fabs(rv1[l]) + tst1;
  798. if (tst2 == tst1) {
  799. docancellation = 0;
  800. break;
  801. }
  802. l1 = l - 1;
  803. /*
  804. * rv1(1) is always zero, so there is no exit through the
  805. * bottom of the loop
  806. */
  807. tst2 = fabs(w[l - 1]) + tst1;
  808. if (tst2 == tst1)
  809. break;
  810. }
  811. /*
  812. * cancellation of rv1[l] if l > 1
  813. */
  814. if (docancellation) {
  815. c = 0.0;
  816. s = 1.0;
  817. for (i = l; i <= k; i++) {
  818. f = s * rv1[i];
  819. rv1[i] = c * rv1[i];
  820. if ((fabs(f) + tst1) == tst1)
  821. break;
  822. g = w[i];
  823. h = hypot(f, g);
  824. w[i] = h;
  825. h = 1.0 / h;
  826. c = g * h;
  827. s = -f * h;
  828. for (j = 0; j < m; j++) {
  829. double y = a[j][l1];
  830. double z = a[j][i];
  831. a[j][l1] = y * c + z * s;
  832. a[j][i] = z * c - y * s;
  833. }
  834. }
  835. }
  836. /*
  837. * test for convergence
  838. */
  839. z = w[k];
  840. if (l != k) {
  841. int i1;
  842. /*
  843. * shift from bottom 2 by 2 minor
  844. */
  845. x = w[l];
  846. y = w[k1];
  847. g = rv1[k1];
  848. h = rv1[k];
  849. f = 0.5 * (((g + z) / h) * ((g - z) / y) + y / h - h / y);
  850. g = hypot(f, 1.0);
  851. f = x - (z / x) * z + (h / x) * (y / (f + copysign(g, f)) - h);
  852. /*
  853. * next qr transformation
  854. */
  855. c = 1.0;
  856. s = 1.0;
  857. for (i1 = l; i1 < k; i1++) {
  858. i = i1 + 1;
  859. g = rv1[i];
  860. y = w[i];
  861. h = s * g;
  862. g = c * g;
  863. z = hypot(f, h);
  864. rv1[i1] = z;
  865. c = f / z;
  866. s = h / z;
  867. f = x * c + g * s;
  868. g = g * c - x * s;
  869. h = y * s;
  870. y *= c;
  871. for (j = 0; j < n; j++) {
  872. x = v[j][i1];
  873. z = v[j][i];
  874. v[j][i1] = x * c + z * s;
  875. v[j][i] = z * c - x * s;
  876. }
  877. z = hypot(f, h);
  878. w[i1] = z;
  879. /*
  880. * rotation can be arbitrary if z = 0
  881. */
  882. if (z != 0.0) {
  883. c = f / z;
  884. s = h / z;
  885. }
  886. f = c * g + s * y;
  887. x = c * y - s * g;
  888. for (j = 0; j < m; j++) {
  889. y = a[j][i1];
  890. z = a[j][i];
  891. a[j][i1] = y * c + z * s;
  892. a[j][i] = z * c - y * s;
  893. }
  894. }
  895. rv1[l] = 0.0;
  896. rv1[k] = f;
  897. w[k] = x;
  898. } else {
  899. /*
  900. * w[k] is made non-negative
  901. */
  902. if (z < 0.0) {
  903. w[k] = -z;
  904. for (j = 0; j < n; j++)
  905. v[j][k] = -v[j][k];
  906. }
  907. break;
  908. }
  909. }
  910. }
  911. free(rv1);
  912. }
  913. /* Least squares fitting via singular value decomposition.
  914. */
  915. static void lsq(double** A, int ni, int nj, double* z, double* w, double* sol)
  916. {
  917. double** V = alloc2d(ni, ni, sizeof(double));
  918. double** B = alloc2d(nj, ni, sizeof(double));
  919. int i, j, ii;
  920. svd(A, ni, nj, w, V);
  921. for (j = 0; j < ni; ++j)
  922. for (i = 0; i < ni; ++i)
  923. V[j][i] /= w[i];
  924. for (i = 0; i < ni; ++i) {
  925. double* v = V[i];
  926. for (j = 0; j < nj; ++j) {
  927. double* a = A[j];
  928. double* b = &B[i][j];
  929. for (ii = 0; ii < ni; ++ii)
  930. *b += v[ii] * a[ii];
  931. }
  932. }
  933. for (i = 0; i < ni; ++i)
  934. sol[i] = 0.0;
  935. for (i = 0; i < ni; ++i)
  936. for (j = 0; j < nj; ++j)
  937. sol[i] += B[i][j] * z[j];
  938. free2d(B);
  939. free2d(V);
  940. }
  941. /*
  942. * square->coeffs[]:
  943. *
  944. * ---------------------
  945. * | 3 10 17 24 |
  946. * | 6 13 20 |
  947. * | 2 9 16 23 |
  948. * | 5 12 19 |
  949. * | 1 8 15 22 |
  950. * | 4 11 18 |
  951. * | 0 7 14 21 |
  952. * ---------------------
  953. */
  954. /* Calculates spline coefficients in each primary triangle by least squares
  955. * fitting to data attached by csa_attachpoints().
  956. */
  957. static void csa_findprimarycoeffs(csa* a)
  958. {
  959. int n[4] = { 0, 0, 0, 0 };
  960. int i;
  961. if (csa_verbose)
  962. fprintf(stderr, "calculating spline coefficients for primary triangles:\n ");
  963. for (i = 0; i < a->npt; ++i) {
  964. triangle* t = a->pt[i];
  965. int npoints = t->npoints;
  966. point** points = t->points;
  967. double* z = malloc(npoints * sizeof(double));
  968. int q = n2q(t->npoints);
  969. int ok = 1;
  970. double b[10];
  971. double b1[6];
  972. int ii;
  973. if (csa_verbose) {
  974. fprintf(stderr, ".");
  975. fflush(stderr);
  976. }
  977. for (ii = 0; ii < npoints; ++ii)
  978. z[ii] = points[ii]->z;
  979. do {
  980. double bc[3];
  981. double wmin, wmax;
  982. if (!ok)
  983. q--;
  984. assert(q >= 0);
  985. if (q == 3) {
  986. double** A = alloc2d(10, npoints, sizeof(double));
  987. double w[10];
  988. for (ii = 0; ii < npoints; ++ii) {
  989. double* aii = A[ii];
  990. double tmp;
  991. triangle_calculatebc(t, points[ii], bc);
  992. /*
  993. * 0 1 2 3 4 5 6 7 8 9
  994. * 300 210 201 120 111 102 030 021 012 003
  995. */
  996. tmp = bc[0] * bc[0];
  997. aii[0] = tmp * bc[0];
  998. tmp *= 3.0;
  999. aii[1] = tmp * bc[1];
  1000. aii[2] = tmp * bc[2];
  1001. tmp = bc[1] * bc[1];
  1002. aii[6] = tmp * bc[1];
  1003. tmp *= 3.0;
  1004. aii[3] = tmp * bc[0];
  1005. aii[7] = tmp * bc[2];
  1006. tmp = bc[2] * bc[2];
  1007. aii[9] = tmp * bc[2];
  1008. tmp *= 3.0;
  1009. aii[5] = tmp * bc[0];
  1010. aii[8] = tmp * bc[1];
  1011. aii[4] = bc[0] * bc[1] * bc[2] * 6.0;
  1012. }
  1013. lsq(A, 10, npoints, z, w, b);
  1014. wmin = w[0];
  1015. wmax = w[0];
  1016. for (ii = 1; ii < 10; ++ii) {
  1017. if (w[ii] < wmin)
  1018. wmin = w[ii];
  1019. else if (w[ii] > wmax)
  1020. wmax = w[ii];
  1021. }
  1022. if (wmin < wmax / a->k)
  1023. ok = 0;
  1024. free2d(A);
  1025. } else if (q == 2) {
  1026. double** A = alloc2d(6, npoints, sizeof(double));
  1027. double w[6];
  1028. for (ii = 0; ii < npoints; ++ii) {
  1029. double* aii = A[ii];
  1030. triangle_calculatebc(t, points[ii], bc);
  1031. /*
  1032. * 0 1 2 3 4 5
  1033. * 200 110 101 020 011 002
  1034. */
  1035. aii[0] = bc[0] * bc[0];
  1036. aii[1] = bc[0] * bc[1] * 2.0;
  1037. aii[2] = bc[0] * bc[2] * 2.0;
  1038. aii[3] = bc[1] * bc[1];
  1039. aii[4] = bc[1] * bc[2] * 2.0;
  1040. aii[5] = bc[2] * bc[2];
  1041. }
  1042. lsq(A, 6, npoints, z, w, b1);
  1043. wmin = w[0];
  1044. wmax = w[0];
  1045. for (ii = 1; ii < 6; ++ii) {
  1046. if (w[ii] < wmin)
  1047. wmin = w[ii];
  1048. else if (w[ii] > wmax)
  1049. wmax = w[ii];
  1050. }
  1051. if (wmin < wmax / a->k)
  1052. ok = 0;
  1053. else { /* degree raising */
  1054. ok = 1;
  1055. b[0] = b1[0];
  1056. b[1] = (b1[0] + 2.0 * b1[1]) / 3.0;
  1057. b[2] = (b1[0] + 2.0 * b1[2]) / 3.0;
  1058. b[3] = (b1[3] + 2.0 * b1[1]) / 3.0;
  1059. b[4] = (b1[1] + b1[2] + b1[4]) / 3.0;
  1060. b[5] = (b1[5] + 2.0 * b1[2]) / 3.0;
  1061. b[6] = b1[3];
  1062. b[7] = (b1[3] + 2.0 * b1[4]) / 3.0;
  1063. b[8] = (b1[5] + 2.0 * b1[4]) / 3.0;
  1064. b[9] = b1[5];
  1065. }
  1066. free2d(A);
  1067. } else if (q == 1) {
  1068. double** A = alloc2d(3, npoints, sizeof(double));
  1069. double w[3];
  1070. for (ii = 0; ii < npoints; ++ii) {
  1071. double* aii = A[ii];
  1072. triangle_calculatebc(t, points[ii], bc);
  1073. aii[0] = bc[0];
  1074. aii[1] = bc[1];
  1075. aii[2] = bc[2];
  1076. }
  1077. lsq(A, 3, npoints, z, w, b1);
  1078. wmin = w[0];
  1079. wmax = w[0];
  1080. for (ii = 1; ii < 3; ++ii) {
  1081. if (w[ii] < wmin)
  1082. wmin = w[ii];
  1083. else if (w[ii] > wmax)
  1084. wmax = w[ii];
  1085. }
  1086. if (wmin < wmax / a->k)
  1087. ok = 0;
  1088. else { /* degree raising */
  1089. ok = 1;
  1090. b[0] = b1[0];
  1091. b[1] = (2.0 * b1[0] + b1[1]) / 3.0;
  1092. b[2] = (2.0 * b1[0] + b1[2]) / 3.0;
  1093. b[3] = (2.0 * b1[1] + b1[0]) / 3.0;
  1094. b[4] = (b1[0] + b1[1] + b1[2]) / 3.0;
  1095. b[5] = (2.0 * b1[2] + b1[0]) / 3.0;
  1096. b[6] = b1[1];
  1097. b[7] = (2.0 * b1[1] + b1[2]) / 3.0;
  1098. b[8] = (2.0 * b1[2] + b1[1]) / 3.0;
  1099. b[9] = b1[2];
  1100. }
  1101. free2d(A);
  1102. } else if (q == 0) {
  1103. double** A = alloc2d(1, npoints, sizeof(double));
  1104. double w[1];
  1105. for (ii = 0; ii < npoints; ++ii)
  1106. A[ii][0] = 1.0;
  1107. lsq(A, 1, npoints, z, w, b1);
  1108. ok = 1;
  1109. b[0] = b1[0];
  1110. b[1] = b1[0];
  1111. b[2] = b1[0];
  1112. b[3] = b1[0];
  1113. b[4] = b1[0];
  1114. b[5] = b1[0];
  1115. b[6] = b1[0];
  1116. b[7] = b1[0];
  1117. b[8] = b1[0];
  1118. b[9] = b1[0];
  1119. free2d(A);
  1120. }
  1121. } while (!ok);
  1122. n[q]++;
  1123. t->order = q;
  1124. {
  1125. square* s = t->parent;
  1126. double* coeffs = s->coeffs;
  1127. coeffs[12] = b[0];
  1128. coeffs[9] = b[1];
  1129. coeffs[6] = b[3];
  1130. coeffs[3] = b[6];
  1131. coeffs[2] = b[7];
  1132. coeffs[1] = b[8];
  1133. coeffs[0] = b[9];
  1134. coeffs[4] = b[5];
  1135. coeffs[8] = b[2];
  1136. coeffs[5] = b[4];
  1137. }
  1138. free(z);
  1139. }
  1140. if (csa_verbose) {
  1141. fprintf(stderr, "\n 3rd order -- %d sets\n", n[3]);
  1142. fprintf(stderr, " 2nd order -- %d sets\n", n[2]);
  1143. fprintf(stderr, " 1st order -- %d sets\n", n[1]);
  1144. fprintf(stderr, " 0th order -- %d sets\n", n[0]);
  1145. fflush(stderr);
  1146. }
  1147. if (csa_verbose == 2) {
  1148. int j;
  1149. fprintf(stderr, " j\\i");
  1150. for (i = 0; i < a->ni; ++i)
  1151. fprintf(stderr, "%2d ", i);
  1152. fprintf(stderr, "\n");
  1153. for (j = a->nj - 1; j >= 0; --j) {
  1154. fprintf(stderr, "%2d ", j);
  1155. for (i = 0; i < a->ni; ++i) {
  1156. square* s = a->squares[j][i];
  1157. if (s->triangles[0]->primary)
  1158. fprintf(stderr, "%2d ", s->triangles[0]->order);
  1159. else
  1160. fprintf(stderr, " . ");
  1161. }
  1162. fprintf(stderr, "\n");
  1163. }
  1164. }
  1165. }
  1166. /* Finds spline coefficients in (adjacent to primary triangles) secondary
  1167. * triangles from C1 smoothness conditions.
  1168. */
  1169. static void csa_findsecondarycoeffs(csa* a)
  1170. {
  1171. square*** squares = a->squares;
  1172. int ni = a->ni;
  1173. int nj = a->nj;
  1174. int ii;
  1175. if (csa_verbose) {
  1176. fprintf(stderr, "propagating spline coefficients to the remaining triangles:\n");
  1177. fflush(stderr);
  1178. }
  1179. /*
  1180. * red
  1181. */
  1182. for (ii = 0; ii < a->npt; ++ii) {
  1183. triangle* t = a->pt[ii];
  1184. square* s = t->parent;
  1185. int i = s->i;
  1186. int j = s->j;
  1187. double* c = s->coeffs;
  1188. double* cl = (i > 0) ? squares[j][i - 1]->coeffs : NULL;
  1189. double* cb = (j > 0) ? squares[j - 1][i]->coeffs : NULL;
  1190. double* cbl = (i > 0 && j > 0) ? squares[j - 1][i - 1]->coeffs : NULL;
  1191. double* ca = (j < nj - 1) ? squares[j + 1][i]->coeffs : NULL;
  1192. double* cal = (j < nj - 1 && i > 0) ? squares[j + 1][i - 1]->coeffs : NULL;
  1193. c[7] = 2.0 * c[4] - c[1];
  1194. c[11] = 2.0 * c[8] - c[5];
  1195. c[15] = 2.0 * c[12] - c[9];
  1196. c[10] = 2.0 * c[6] - c[2];
  1197. c[13] = 2.0 * c[9] - c[5];
  1198. c[16] = 2.0 * c[12] - c[8];
  1199. c[19] = 2.0 * c[15] - c[11];
  1200. if (cl != NULL) {
  1201. cl[21] = c[0];
  1202. cl[22] = c[1];
  1203. cl[23] = c[2];
  1204. cl[24] = c[3];
  1205. cl[18] = c[0] + c[1] - c[4];
  1206. cl[19] = c[1] + c[2] - c[5];
  1207. cl[20] = c[2] + c[3] - c[6];
  1208. cl[17] = 2.0 * cl[20] - cl[23];
  1209. cl[14] = 2.0 * cl[18] - cl[22];
  1210. }
  1211. if (cb != NULL) {
  1212. cb[3] = c[0];
  1213. cb[10] = c[7];
  1214. cb[6] = c[0] + c[7] - c[4];
  1215. cb[2] = 2.0 * cb[6] - cb[10];
  1216. }
  1217. if (cbl != NULL) {
  1218. cbl[23] = cb[2];
  1219. cbl[24] = cb[3];
  1220. cbl[20] = cb[2] + cb[3] - cb[6];
  1221. cbl[17] = cl[14];
  1222. }
  1223. if (ca != NULL) {
  1224. ca[0] = c[3];
  1225. ca[7] = c[10];
  1226. ca[4] = c[3] + c[10] - c[6];
  1227. ca[1] = 2.0 * ca[4] - ca[7];
  1228. }
  1229. if (cal != NULL) {
  1230. cal[21] = c[3];
  1231. cal[22] = ca[1];
  1232. cal[18] = ca[0] + ca[1] - ca[4];
  1233. cal[14] = cl[17];
  1234. }
  1235. }
  1236. /*
  1237. * blue
  1238. */
  1239. for (ii = 0; ii < a->npt; ++ii) {
  1240. triangle* t = a->pt[ii];
  1241. square* s = t->parent;
  1242. int i = s->i;
  1243. int j = s->j;
  1244. double* c = s->coeffs;
  1245. double* cr = (i < ni - 1) ? squares[j][i + 1]->coeffs : NULL;
  1246. double* car = (i < ni - 1 && j < nj - 1) ? squares[j + 1][i + 1]->coeffs : NULL;
  1247. double* cbr = (i < ni - 1 && j > 0) ? squares[j - 1][i + 1]->coeffs : NULL;
  1248. if (car != NULL)
  1249. cr[13] = car[7] + car[14] - car[11];
  1250. if (cbr != NULL)
  1251. cr[11] = cbr[10] + cbr[17] - cbr[13];
  1252. if (cr != NULL)
  1253. cr[5] = c[22] + c[23] - c[19];
  1254. }
  1255. /*
  1256. * green & yellow
  1257. */
  1258. for (ii = 0; ii < a->npt; ++ii) {
  1259. triangle* t = a->pt[ii];
  1260. square* s = t->parent;
  1261. int i = s->i;
  1262. int j = s->j;
  1263. double* cr = (i < ni - 1) ? squares[j][i + 1]->coeffs : NULL;
  1264. if (cr != NULL) {
  1265. cr[9] = (cr[5] + cr[13]) / 2.0;
  1266. cr[8] = (cr[5] + cr[11]) / 2.0;
  1267. cr[15] = (cr[11] + cr[19]) / 2.0;
  1268. cr[16] = (cr[13] + cr[19]) / 2.0;
  1269. cr[12] = (cr[8] + cr[16]) / 2.0;
  1270. }
  1271. }
  1272. if (csa_verbose) {
  1273. fprintf(stderr, "checking that all coefficients have been set:\n");
  1274. fflush(stderr);
  1275. }
  1276. for (ii = 0; ii < ni * nj; ++ii) {
  1277. square* s = squares[0][ii];
  1278. double* c = s->coeffs;
  1279. int i;
  1280. if (s->npoints == 0)
  1281. continue;
  1282. for (i = 0; i < 25; ++i)
  1283. if (isnan(c[i]))
  1284. fprintf(stderr, " squares[%d][%d]->coeffs[%d] = NaN\n", s->j, s->i, i);
  1285. }
  1286. }
  1287. static int i300[] = { 12, 12, 12, 12 };
  1288. static int i030[] = { 3, 24, 21, 0 };
  1289. static int i003[] = { 0, 3, 24, 21 };
  1290. static int i210[] = { 9, 16, 15, 8 };
  1291. static int i021[] = { 2, 17, 22, 7 };
  1292. static int i102[] = { 4, 6, 20, 18 };
  1293. static int i120[] = { 6, 20, 18, 4 };
  1294. static int i012[] = { 1, 10, 23, 14 };
  1295. static int i201[] = { 8, 9, 16, 15 };
  1296. static int i111[] = { 5, 13, 19, 11 };
  1297. static int* iall[] = { i300, i030, i003, i210, i021, i102, i120, i012, i201, i111 };
  1298. static void csa_sethascoeffsflag(csa* a)
  1299. {
  1300. int i, j;
  1301. for (j = 0; j < a->nj; ++j) {
  1302. for (i = 0; i < a->ni; ++i) {
  1303. square* s = a->squares[j][i];
  1304. double* coeffs = s->coeffs;
  1305. int ii;
  1306. for (ii = 0; ii < 4; ++ii) {
  1307. triangle* t = s->triangles[ii];
  1308. int cc;
  1309. for (cc = 0; cc < 10; ++cc)
  1310. if (isnan(coeffs[iall[cc][ii]]))
  1311. break;
  1312. if (cc == 10)
  1313. t->hascoeffs = 1;
  1314. }
  1315. }
  1316. }
  1317. }
  1318. void csa_calculatespline(csa* a)
  1319. {
  1320. csa_squarize(a);
  1321. csa_attachpoints(a);
  1322. csa_findprimarycoeffs(a);
  1323. csa_findsecondarycoeffs(a);
  1324. csa_sethascoeffsflag(a);
  1325. }
  1326. void csa_approximate_point(csa* a, point* p)
  1327. {
  1328. double h = a->h;
  1329. double ii = (p->x - a->xmin) / h + 1.0;
  1330. double jj = (p->y - a->ymin) / h + 1.0;
  1331. int i, j;
  1332. square* s;
  1333. double fi, fj;
  1334. int ti;
  1335. triangle* t;
  1336. double bc[3];
  1337. if (ii < 0.0 || jj < 0.0 || ii > (double) a->ni - 1.0 || jj > (double) a->nj - 1.0) {
  1338. p->z = NaN;
  1339. return;
  1340. }
  1341. i = floor(ii);
  1342. j = floor(jj);
  1343. s = a->squares[j][i];
  1344. fi = ii - i;
  1345. fj = jj - j;
  1346. if (fj < fi) {
  1347. if (fi + fj < 1.0)
  1348. ti = 3;
  1349. else
  1350. ti = 2;
  1351. } else {
  1352. if (fi + fj < 1.0)
  1353. ti = 0;
  1354. else
  1355. ti = 1;
  1356. }
  1357. t = s->triangles[ti];
  1358. if (!t->hascoeffs) {
  1359. p->z = NaN;
  1360. return;
  1361. }
  1362. triangle_calculatebc(t, p, bc);
  1363. {
  1364. double* c = s->coeffs;
  1365. double bc1 = bc[0];
  1366. double bc2 = bc[1];
  1367. double bc3 = bc[2];
  1368. double tmp1 = bc1 * bc1;
  1369. double tmp2 = bc2 * bc2;
  1370. double tmp3 = bc3 * bc3;
  1371. switch (ti) {
  1372. case 0:
  1373. p->z = c[12] * bc1 * tmp1 + c[3] * bc2 * tmp2 + c[0] * bc3 * tmp3 + 3.0 * (c[9] * tmp1 * bc2 + c[2] * tmp2 * bc3 + c[4] * tmp3 * bc1 + c[6] * bc1 * tmp2 + c[1] * bc2 * tmp3 + c[8] * tmp1 * bc3) + 6.0 * c[5] * bc1 * bc2 * bc3;
  1374. break;
  1375. case 1:
  1376. p->z = c[12] * bc1 * tmp1 + c[24] * bc2 * tmp2 + c[3] * bc3 * tmp3 + 3.0 * (c[16] * tmp1 * bc2 + c[17] * tmp2 * bc3 + c[6] * tmp3 * bc1 + c[20] * bc1 * tmp2 + c[10] * bc2 * tmp3 + c[9] * tmp1 * bc3) + 6.0 * c[13] * bc1 * bc2 * bc3;
  1377. break;
  1378. case 2:
  1379. p->z = c[12] * bc1 * tmp1 + c[21] * bc2 * tmp2 + c[24] * bc3 * tmp3 + 3.0 * (c[15] * tmp1 * bc2 + c[22] * tmp2 * bc3 + c[20] * tmp3 * bc1 + c[18] * bc1 * tmp2 + c[23] * bc2 * tmp3 + c[16] * tmp1 * bc3) + 6.0 * c[19] * bc1 * bc2 * bc3;
  1380. break;
  1381. default: /* 3 */
  1382. p->z = c[12] * bc1 * tmp1 + c[0] * bc2 * tmp2 + c[21] * bc3 * tmp3 + 3.0 * (c[8] * tmp1 * bc2 + c[7] * tmp2 * bc3 + c[18] * tmp3 * bc1 + c[4] * bc1 * tmp2 + c[14] * bc2 * tmp3 + c[15] * tmp1 * bc3) + 6.0 * c[11] * bc1 * bc2 * bc3;
  1383. }
  1384. }
  1385. }
  1386. void csa_approximate_points(csa* a, int n, point* points)
  1387. {
  1388. int ii;
  1389. for (ii = 0; ii < n; ++ii)
  1390. csa_approximate_point(a, &points[ii]);
  1391. }
  1392. void csa_setnpmin(csa* a, int npmin)
  1393. {
  1394. a->npmin = npmin;
  1395. }
  1396. void csa_setnpmax(csa* a, int npmax)
  1397. {
  1398. a->npmax = npmax;
  1399. }
  1400. void csa_setk(csa* a, int k)
  1401. {
  1402. a->k = k;
  1403. }
  1404. void csa_setnppc(csa* a, double nppc)
  1405. {
  1406. a->nppc = nppc;
  1407. }
  1408. #if defined(STANDALONE)
  1409. #include "minell.h"
  1410. #define NIMAX 2048
  1411. #define BUFSIZE 10240
  1412. #define STRBUFSIZE 64
  1413. static void points_generate(double xmin, double xmax, double ymin, double ymax, int nx, int ny, int* nout, point** pout)
  1414. {
  1415. double stepx, stepy;
  1416. double x0, xx, yy;
  1417. int i, j, ii;
  1418. if (nx < 1 || ny < 1) {
  1419. *pout = NULL;
  1420. *nout = 0;
  1421. return;
  1422. }
  1423. *nout = nx * ny;
  1424. *pout = malloc(*nout * sizeof(point));
  1425. stepx = (nx > 1) ? (xmax - xmin) / (nx - 1) : 0.0;
  1426. stepy = (ny > 1) ? (ymax - ymin) / (ny - 1) : 0.0;
  1427. x0 = (nx > 1) ? xmin : (xmin + xmax) / 2.0;
  1428. yy = (ny > 1) ? ymin : (ymin + ymax) / 2.0;
  1429. ii = 0;
  1430. for (j = 0; j < ny; ++j) {
  1431. xx = x0;
  1432. for (i = 0; i < nx; ++i) {
  1433. point* p = &(*pout)[ii];
  1434. p->x = xx;
  1435. p->y = yy;
  1436. xx += stepx;
  1437. ii++;
  1438. }
  1439. yy += stepy;
  1440. }
  1441. }
  1442. static int str2double(char* token, double* value)
  1443. {
  1444. char* end = NULL;
  1445. if (token == NULL) {
  1446. *value = NaN;
  1447. return 0;
  1448. }
  1449. *value = strtod(token, &end);
  1450. if (end == token) {
  1451. *value = NaN;
  1452. return 0;
  1453. }
  1454. return 1;
  1455. }
  1456. #define NALLOCATED_START 1024
  1457. /* Reads array of points from a columnar file.
  1458. *
  1459. * @param fname File name (can be "stdin" or "-" for standard input)
  1460. * @param dim Number of dimensions (must be 2 or 3)
  1461. * @param n Pointer to number of points (output)
  1462. * @param points Pointer to array of points [*n] (output) (to be freed)
  1463. */
  1464. void points_read(char* fname, int dim, int* n, point** points)
  1465. {
  1466. FILE* f = NULL;
  1467. int nallocated = NALLOCATED_START;
  1468. char buf[BUFSIZE];
  1469. char seps[] = " ,;\t";
  1470. char* token;
  1471. if (dim < 2 || dim > 3) {
  1472. *n = 0;
  1473. *points = NULL;
  1474. return;
  1475. }
  1476. if (fname == NULL)
  1477. f = stdin;
  1478. else {
  1479. if (strcmp(fname, "stdin") == 0 || strcmp(fname, "-") == 0)
  1480. f = stdin;
  1481. else {
  1482. f = fopen(fname, "r");
  1483. if (f == NULL)
  1484. csa_quit("%s: %s\n", fname, strerror(errno));
  1485. }
  1486. }
  1487. *points = malloc(nallocated * sizeof(point));
  1488. *n = 0;
  1489. while (fgets(buf, BUFSIZE, f) != NULL) {
  1490. point* p;
  1491. if (*n == nallocated) {
  1492. nallocated *= 2;
  1493. *points = realloc(*points, nallocated * sizeof(point));
  1494. }
  1495. p = &(*points)[*n];
  1496. if (buf[0] == '#')
  1497. continue;
  1498. if ((token = strtok(buf, seps)) == NULL)
  1499. continue;
  1500. if (!str2double(token, &p->x))
  1501. continue;
  1502. if ((token = strtok(NULL, seps)) == NULL)
  1503. continue;
  1504. if (!str2double(token, &p->y))
  1505. continue;
  1506. if (dim == 2)
  1507. p->z = NaN;
  1508. else {
  1509. if ((token = strtok(NULL, seps)) == NULL)
  1510. continue;
  1511. if (!str2double(token, &p->z))
  1512. continue;
  1513. }
  1514. (*n)++;
  1515. }
  1516. if (*n == 0) {
  1517. free(*points);
  1518. *points = NULL;
  1519. } else
  1520. *points = realloc(*points, *n * sizeof(point));
  1521. if (f != stdin)
  1522. if (fclose(f) != 0)
  1523. csa_quit("%s: %s\n", fname, strerror(errno));
  1524. }
  1525. static void points_write(int n, point* points)
  1526. {
  1527. int i;
  1528. if (csa_verbose)
  1529. printf("Output:\n");
  1530. for (i = 0; i < n; ++i) {
  1531. point* p = &points[i];
  1532. printf("%.15g %.15g %.15g\n", p->x, p->y, p->z);
  1533. }
  1534. }
  1535. static double points_scaletosquare(int n, point* points)
  1536. {
  1537. double xmin, ymin, xmax, ymax;
  1538. double k;
  1539. int i;
  1540. if (n <= 0)
  1541. return NaN;
  1542. xmin = xmax = points[0].x;
  1543. ymin = ymax = points[0].y;
  1544. for (i = 1; i < n; ++i) {
  1545. point* p = &points[i];
  1546. if (p->x < xmin)
  1547. xmin = p->x;
  1548. else if (p->x > xmax)
  1549. xmax = p->x;
  1550. if (p->y < ymin)
  1551. ymin = p->y;
  1552. else if (p->y > ymax)
  1553. ymax = p->y;
  1554. }
  1555. if (xmin == xmax || ymin == ymax)
  1556. return NaN;
  1557. else
  1558. k = (ymax - ymin) / (xmax - xmin);
  1559. for (i = 0; i < n; ++i)
  1560. points[i].y /= k;
  1561. return k;
  1562. }
  1563. static void points_scale(int n, point* points, double k)
  1564. {
  1565. int i;
  1566. for (i = 0; i < n; ++i)
  1567. points[i].y /= k;
  1568. }
  1569. static void usage()
  1570. {
  1571. printf("Usage: csabathy -i <XYZ file> {-o <XY file>|-n <nx>x<ny> [-c|-s] [-z <zoom>]}\n");
  1572. printf(" [-v|-V] [-P nppc=<value>] [-P k=<value>]\n");
  1573. printf("Options:\n");
  1574. printf(" -c -- scale internally so that the minimal ellipse turns into a\n");
  1575. printf(" circle (this produces results invariant to affine\n");
  1576. printf(" transformations)\n");
  1577. printf(" -i <XYZ file> -- three-column file with points to approximate from (use\n");
  1578. printf(" \"-i stdin\" or \"-i -\" for standard input)\n");
  1579. printf(" -n <nx>x<ny> -- generate <nx>x<ny> output rectangular grid\n");
  1580. printf(" -o <XY file> -- two-column file with points to approximate in (use\n");
  1581. printf(" \"-o stdin\" or \"-o -\" for standard input)\n");
  1582. printf(" -s -- scale internally so that Xmax - Xmin = Ymax - Ymin\n");
  1583. printf(" -v -- verbose / version\n");
  1584. printf(" -z <zoom> -- zoom in (if <zoom> < 1) or out (<zoom> > 1)\n");
  1585. printf(" -P nppc=<value> -- set the average number of points per cell (default = 5\n");
  1586. printf(" increase if the point distribution is strongly non-uniform\n");
  1587. printf(" to get larger cells)\n");
  1588. printf(" -P k=<value> -- set the spline sensitivity (default = 140, reduce to get\n");
  1589. printf(" smoother results)\n");
  1590. printf(" -V -- very verbose / version\n");
  1591. printf("Description:\n");
  1592. printf(" `csabathy…

Large files files are truncated, but you can click here to view the full file