vector.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. #define _ISOC99_SOURCE /* to get isfinite() */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include <grass/gis.h>
  7. #include <grass/glocale.h>
  8. #include "list.h"
  9. #include "mapcalc.h"
  10. #include "vector.h"
  11. typedef struct Vecfunc
  12. {
  13. char *name;
  14. void *func;
  15. char *proto;
  16. } VECFUNC;
  17. static VECFUNC vf[] = {
  18. {"v_copy", v_copy, "p=rp"},
  19. {"v_add", v_add, "p=rpp"},
  20. {"pnt_op_func_+", v_add, "p=rpp"},
  21. {"v_sub", v_sub, "p=rpp"},
  22. {"pnt_op_func_-", v_sub, "p=rpp"},
  23. {"v_abs", v_abs, "p=rp"},
  24. {"v_neg", v_neg, "p=rp"},
  25. {"pnt_op_func__", v_neg, "p=rp"},
  26. {"v_mul", v_mul, "p=rpd"},
  27. {"pnt_op_func_*", v_mul, "p=rpd"},
  28. {"v_div", v_div, "p=rpd"},
  29. {"pnt_op_func_/", v_div, "p=rpd"},
  30. {"v_unit", v_unit, "p=rp"},
  31. {"v_cross", v_cross, "p=rpp"},
  32. {"pnt_op_func_^", v_cross, "p=rpp"},
  33. {"v_val", v_val, "d=p"},
  34. {"v_dot", v_dot, "d=pp"},
  35. {"pnt_op_func_%", v_dot, "d=pp"},
  36. {"v_area", v_area, "d=pp"},
  37. {"v_eq", v_eq, "d=pp"},
  38. {"v_eq_epsilon", v_eq_epsilon, "d=ppp"},
  39. {"v_isortho", v_isortho, "d=pp"},
  40. {"v_ispara", v_ispara, "d=pp"},
  41. {"v_isacute", v_isacute, "d=pp"},
  42. {NULL, NULL, NULL}
  43. };
  44. typedef VECTOR *(*p_func) (void);
  45. typedef VECTOR *(*p_func_p) (void *p0);
  46. typedef VECTOR *(*p_func_pp) (void *p0, void *p1);
  47. typedef VECTOR *(*p_func_ppp) (void *p0, void *p1, void *p2);
  48. typedef VECTOR *(*p_func_ppd) (void *p0, void *p1, double d);
  49. double nanval;
  50. static VECTOR pnt_o = { NULL, 0, 0, 0, 1 };
  51. static VECTOR pnt_i = { NULL, 1, 0, 0, 1 };
  52. static VECTOR pnt_j = { NULL, 0, 1, 0, 1 };
  53. static VECTOR pnt_k = { NULL, 0, 0, 1, 1 };
  54. void init_vec(void);
  55. void printvec(SYMBOL * sym);
  56. void showvec(SYMBOL * sym);
  57. void setpnt(SYMBOL * var, SYMBOL * pnt);
  58. SYMBOL *mkpnt(double x, double y, double z);
  59. SYMBOL *mkpntvar(SYMBOL * var, SYMBOL * pnt);
  60. SYMBOL *pntfunc(SYMBOL * func, SYMBOL * arglist);
  61. SYMBOL *pntop(int op, SYMBOL * pnt1, SYMBOL * pnt2);
  62. SYMBOL *pntapp(SYMBOL * head, SYMBOL * elt);
  63. VECTOR *v_copy(VECTOR * p, VECTOR * p1);
  64. VECTOR *v_add(VECTOR * p, VECTOR * p1, VECTOR * p2);
  65. VECTOR *v_sub(VECTOR * p, VECTOR * p1, VECTOR * p2);
  66. VECTOR *v_abs(VECTOR * p, VECTOR * p1);
  67. VECTOR *v_neg(VECTOR * p, VECTOR * p1);
  68. static inline int _is_zero(double r);
  69. double v_eq(VECTOR * p1, VECTOR * p2);
  70. double v_eq_epsilon(VECTOR * p1, VECTOR * p2, VECTOR * e);
  71. VECTOR *v_mul(VECTOR * p, VECTOR * p1, double d);
  72. VECTOR *v_div(VECTOR * p, VECTOR * p1, double d);
  73. double v_val(VECTOR * p);
  74. VECTOR *v_unit(VECTOR * p, VECTOR * p1);
  75. double v_dot(VECTOR * p1, VECTOR * p2);
  76. VECTOR *v_cross(VECTOR * p, VECTOR * p1, VECTOR * p2);
  77. double v_isortho(VECTOR * p1, VECTOR * p2);
  78. double v_ispara(VECTOR * p1, VECTOR * p2);
  79. double v_isacute(VECTOR * p1, VECTOR * p2);
  80. double v_area(VECTOR * p1, VECTOR * p2);
  81. void init_vec(void)
  82. {
  83. SYMBOL *sym;
  84. int i;
  85. for (i = 0; vf[i].name; i++) {
  86. sym = putsym(vf[i].name);
  87. switch (vf[i].proto[0]) {
  88. case 'p':
  89. sym->type = st_pfunc;
  90. sym->rettype = st_pnt;
  91. break;
  92. case 'd':
  93. sym->type = st_nfunc;
  94. sym->rettype = st_num;
  95. break;
  96. }
  97. sym->itype = sym->type;
  98. sym->v.p = vf[i].func;
  99. sym->proto = vf[i].proto + 2;
  100. }
  101. /* add some handy constants */
  102. sym = putsym("pnt_o");
  103. sym->type = sym->itype = st_pnt;
  104. sym->v.p = &pnt_o;
  105. sym = putsym("pnt_i");
  106. sym->type = sym->itype = st_pnt;
  107. sym->v.p = &pnt_i;
  108. sym = putsym("pnt_j");
  109. sym->type = sym->itype = st_pnt;
  110. sym->v.p = &pnt_j;
  111. sym = putsym("pnt_k");
  112. sym->type = sym->itype = st_pnt;
  113. sym->v.p = &pnt_k;
  114. /* initialize NaN */
  115. nanval = 0.0 / 0.0;
  116. }
  117. void printvec(SYMBOL * sym)
  118. {
  119. VECTOR *v;
  120. v = (VECTOR *) sym->v.p;
  121. fprintf(stdout, "\t(");
  122. if (!isfinite(v->x))
  123. fprintf(stdout, "??.??");
  124. else if (v->x == (int)v->x)
  125. fprintf(stdout, "%d", (int)v->x);
  126. else
  127. fprintf(stdout, "%g", v->x);
  128. fprintf(stdout, ", ");
  129. if (!isfinite(v->y))
  130. fprintf(stdout, "??.??");
  131. else if (v->y == (int)v->y)
  132. fprintf(stdout, "%d", (int)v->y);
  133. else
  134. fprintf(stdout, "%g", v->y);
  135. if (isfinite(v->z)) {
  136. fprintf(stdout, ", ");
  137. if (v->z == (int)v->z)
  138. fprintf(stdout, "%d", (int)v->z);
  139. else
  140. fprintf(stdout, "%g", v->z);
  141. }
  142. fprintf(stdout, ")\n");
  143. }
  144. void showvec(SYMBOL * sym)
  145. {
  146. VECTOR *v;
  147. v = (VECTOR *) sym->v.p;
  148. printvec(sym);
  149. if (v && --v->refcnt > 0)
  150. sym->v.p = NULL;
  151. freesym(sym);
  152. }
  153. void setpnt(SYMBOL * var, SYMBOL * pnt)
  154. {
  155. SYMBOL *sym;
  156. if (var->name) {
  157. sym = getsym(var->name);
  158. if (sym) {
  159. if (--((VECTOR *) sym->v.p)->refcnt < 1)
  160. G_free(sym->v.p);
  161. /*
  162. * If refcnt(pnt) == 1, this was anonymous, else it's used
  163. * somewhere else. Must we dup then?
  164. */
  165. sym->v.p = pnt->v.p;
  166. }
  167. }
  168. if (--((VECTOR *) var->v.p)->refcnt < 1)
  169. G_free(var->v.p);
  170. var->v.p = NULL;
  171. freesym(var);
  172. printvec(pnt);
  173. pnt->v.p = NULL;
  174. freesym(pnt);
  175. }
  176. SYMBOL *mkpnt(double x, double y, double z)
  177. {
  178. SYMBOL *pnt;
  179. VECTOR *vec;
  180. vec = (VECTOR *) listitem(sizeof(VECTOR));
  181. vec->x = x;
  182. vec->y = y;
  183. vec->z = z;
  184. vec->refcnt = 1;
  185. pnt = (SYMBOL *) listitem(sizeof(SYMBOL));
  186. pnt->type = pnt->itype = st_pnt;
  187. pnt->v.p = vec;
  188. return pnt;
  189. }
  190. SYMBOL *mkpntvar(SYMBOL * var, SYMBOL * pnt)
  191. {
  192. var->type = var->itype = st_pnt;
  193. var->name = var->v.p;
  194. var->v.p = pnt->v.p;
  195. pnt->v.p = NULL;
  196. freesym(pnt);
  197. symtab = (SYMBOL *) listadd((LIST *) symtab, (LIST *) var, cmpsymsym);
  198. printvec(var);
  199. return var;
  200. }
  201. SYMBOL *pntfunc(SYMBOL * func, SYMBOL * arglist)
  202. {
  203. SYMBOL *sym, *sptr;
  204. VECTOR *res = NULL;
  205. int argc = -1, i;
  206. sym = (SYMBOL *) listitem(sizeof(SYMBOL));
  207. sym->type = sym->itype = st_pnt;
  208. if (!func || !func->v.p || func->type != st_pfunc) {
  209. parseerror = 1;
  210. G_warning(_("Can't call bad function"));
  211. }
  212. else
  213. argc = listcnt((LIST *) arglist);
  214. for (i = 0, sptr = arglist; sptr; sptr = sptr->next, i++) {
  215. if (func->proto[i] == 'r')
  216. i++;
  217. if (func->proto[i] == 'p') {
  218. if (sptr->itype != st_pnt || !sptr->v.p)
  219. argc = -1;
  220. }
  221. else if (func->proto[i] == 'd' && sptr->itype != st_num)
  222. argc = -1;
  223. }
  224. res = (VECTOR *) listitem(sizeof(VECTOR));
  225. if (argc == 0 && (!func->proto || !*func->proto))
  226. res = (*(p_func) func->v.p) ();
  227. else if (argc == 1 && !strcmp(func->proto, "p"))
  228. res = (*(p_func_p) func->v.p) (arglist->v.p);
  229. else if (argc == 1 && !strcmp(func->proto, "rp"))
  230. res = (*(p_func_pp) func->v.p) (res, arglist->v.p);
  231. else if (argc == 2 && !strcmp(func->proto, "rpd"))
  232. res = (*(p_func_ppd) func->v.p) (res, arglist->v.p,
  233. arglist->next->v.d);
  234. else if (argc == 2 && !strcmp(func->proto, "pp"))
  235. res = (*(p_func_pp) func->v.p) (arglist->v.p, arglist->next->v.p);
  236. else if (argc == 2 && !strcmp(func->proto, "rpp"))
  237. res = (*(p_func_ppp) func->v.p) (res, arglist->v.p,
  238. arglist->next->v.p);
  239. else if (argc == 3 && !strcmp(func->proto, "ppp"))
  240. res = (*(p_func_ppp) func->v.p) (arglist->v.p,
  241. arglist->next->v.p,
  242. arglist->next->next->v.p);
  243. else {
  244. G_warning(_("Bad arguments to pointfunc %s"), func->name);
  245. parseerror = 1;
  246. sym = (SYMBOL *) listdelall((LIST *) sym, freesym);
  247. if (res)
  248. G_free(res);
  249. return NULL;
  250. }
  251. sym->v.p = res;
  252. listdelall((LIST *) arglist, freesym);
  253. return sym;
  254. }
  255. SYMBOL *pntop(int op, SYMBOL * pnt1, SYMBOL * pnt2)
  256. {
  257. SYMBOL *func, *arglist, *res = NULL;
  258. char buf[32];
  259. sprintf(buf, "pnt_op_func_%c", op);
  260. func = getsym(buf);
  261. if (!func) {
  262. G_warning(_("No function defined to perform ``point %c point''"), op);
  263. parseerror = 1;
  264. }
  265. else if (func->rettype == st_pnt) {
  266. res = (SYMBOL *) listitem(sizeof(SYMBOL));
  267. symcpy(res, func);
  268. res->next = NULL;
  269. func = res;
  270. arglist = (SYMBOL *) listapp(NULL, (LIST *) pnt1);
  271. arglist = (SYMBOL *) listapp((LIST *) arglist, (LIST *) pnt2);
  272. res = pntfunc(func, arglist);
  273. }
  274. return res;
  275. }
  276. SYMBOL *pntapp(SYMBOL * head, SYMBOL * elt)
  277. {
  278. return (SYMBOL *) listapp((LIST *) head, (LIST *) elt);
  279. }
  280. /*
  281. * Utility function to copy a point: p = p1;
  282. * The dimension (2D/3D) depends on p1. Note, that copying a constant
  283. * will always yield 3D.
  284. */
  285. VECTOR *v_copy(VECTOR * p, VECTOR * p1)
  286. {
  287. p->x = p1->x;
  288. p->y = p1->y;
  289. p->z = p1->z;
  290. return p;
  291. }
  292. /*
  293. * Vector addition
  294. * Result is 2D if at least one of p1 or p2 is 2D.
  295. */
  296. VECTOR *v_add(VECTOR * p, VECTOR * p1, VECTOR * p2)
  297. {
  298. p->x = p1->x + p2->x;
  299. p->y = p1->y + p2->y;
  300. /*
  301. * resist the tentation setting p->z to nanval and then testing for
  302. * dimension, as p might be the same as p1 or p2
  303. */
  304. if (!isnan(p1->z) && !isnan(p2->z))
  305. p->z = p1->z + p2->z;
  306. else
  307. p->z = nanval;
  308. return p;
  309. }
  310. /*
  311. * Vector substraction
  312. * Result is 2D if at least one of p1 or p2 is 2D.
  313. */
  314. VECTOR *v_sub(VECTOR * p, VECTOR * p1, VECTOR * p2)
  315. {
  316. p->x = p1->x - p2->x;
  317. p->y = p1->y - p2->y;
  318. if (!isnan(p1->z) && !isnan(p2->z))
  319. p->z = p1->z + p2->z;
  320. else
  321. p->z = nanval;
  322. return p;
  323. }
  324. /*
  325. * Utility function to make all coordinates positive
  326. */
  327. VECTOR *v_abs(VECTOR * p, VECTOR * p1)
  328. {
  329. p->x = fabs(p1->x);
  330. p->y = fabs(p1->y);
  331. if (!isnan(p1->z))
  332. p->z = fabs(p1->z);
  333. else
  334. p->z = nanval;
  335. return p;
  336. }
  337. /*
  338. * Utility function to negate all coordinates
  339. */
  340. VECTOR *v_neg(VECTOR * p, VECTOR * p1)
  341. {
  342. p->x = -p1->x;
  343. p->y = -p1->y;
  344. if (!isnan(p1->z))
  345. p->z = -p1->z;
  346. else
  347. p->z = nanval;
  348. return p;
  349. }
  350. /*
  351. * Utility function to compare two doubles for equality without epsilon
  352. * This is not really true, as we consider NaN to be zero.
  353. */
  354. static inline int _is_zero(double r)
  355. {
  356. if ((isfinite(r) && r == 0.0) || isnan(r))
  357. return 1;
  358. return 0;
  359. }
  360. /*
  361. * Test for equality of two points. No epsion applied
  362. */
  363. double v_eq(VECTOR * p1, VECTOR * p2)
  364. {
  365. VECTOR p;
  366. int dim = 2;
  367. if (!isnan(p1->z) && !isnan(p2->z))
  368. dim = 3;
  369. v_sub(&p, p1, p2);
  370. v_abs(&p, &p);
  371. if (_is_zero(p.x) && _is_zero(p.y) && (dim == 2 || _is_zero(p.z)))
  372. return 1;
  373. return 0;
  374. }
  375. /*
  376. * Test for equality of two points by a given epsilon
  377. * epsilon is supposed to have positive values only.
  378. */
  379. double v_eq_epsilon(VECTOR * p1, VECTOR * p2, VECTOR * e)
  380. {
  381. VECTOR p;
  382. int dim = 2;
  383. if (!isnan(p1->z) && !isnan(p2->z))
  384. dim = 3;
  385. v_sub(&p, p1, p2);
  386. v_abs(&p, &p);
  387. if (p.x < e->x && p.y < e->y && (dim == 2 || (p.z < e->z)))
  388. return 1;
  389. return 0;
  390. }
  391. /*
  392. * Multiply a vector by a scalar
  393. */
  394. VECTOR *v_mul(VECTOR * p, VECTOR * p1, double d)
  395. {
  396. p->x = d * p1->x;
  397. p->y = d * p1->y;
  398. if (!isnan(p1->z))
  399. p->z = d * p1->z;
  400. else
  401. p->z = nanval;
  402. return p;
  403. }
  404. /*
  405. * Divide a vector by a scalar
  406. */
  407. VECTOR *v_div(VECTOR * p, VECTOR * p1, double d)
  408. {
  409. if (!isfinite(d) || d == 0.0) {
  410. parseerror = 1;
  411. return p;
  412. }
  413. p->x = p1->x / d;
  414. p->y = p1->y / d;
  415. if (!isnan(p1->z))
  416. p->z = p1->z / d;
  417. else
  418. p->z = nanval;
  419. return p;
  420. }
  421. /*
  422. * Compute the value of a vector
  423. */
  424. double v_val(VECTOR * p)
  425. {
  426. return sqrt(p->x * p->x + p->y * p->y +
  427. ((isnan(p->z)) ? 0 : p->z * p->z));
  428. }
  429. /*
  430. * The only way to get a value of zero is that P1 is the origin.
  431. * The unit vector of the origin doesn't exist, but we return the
  432. * origin.
  433. */
  434. VECTOR *v_unit(VECTOR * p, VECTOR * p1)
  435. {
  436. double val = v_val(p1);
  437. if (_is_zero(val))
  438. return v_copy(p, &pnt_o);
  439. p->x = p1->x / val;
  440. p->y = p1->y / val;
  441. if (!isnan(p1->z))
  442. p->z = p1->z / val;
  443. else
  444. p->z = nanval;
  445. return p;
  446. }
  447. /*
  448. * Compute the dot product of P1 and P2
  449. */
  450. double v_dot(VECTOR * p1, VECTOR * p2)
  451. {
  452. int dim = 2;
  453. if (!isnan(p1->z) && !isnan(p2->z))
  454. dim = 3;
  455. return p1->x * p2->x + p1->y * p2->y + ((dim == 2) ? 0 : p1->z * p2->z);
  456. }
  457. /*
  458. * Compute the cross product of P1 and P2
  459. * Return (0,0) for 2D
  460. */
  461. VECTOR *v_cross(VECTOR * p, VECTOR * p1, VECTOR * p2)
  462. {
  463. VECTOR p0;
  464. if (!isnan(p1->z) && !isnan(p2->z)) {
  465. p0.x = p1->y * p2->z + p1->z * p2->y;
  466. p0.y = p1->z * p2->x + p1->x * p2->z;
  467. p0.z = p1->x * p2->y + p1->y * p2->x;
  468. v_copy(p, &p0);
  469. }
  470. else {
  471. p->x = p->y = 0;
  472. p->z = nanval;
  473. }
  474. return p;
  475. }
  476. /*
  477. * Decide if vector P1 is ortogonal to vector P2
  478. * Should test if either P1 or P2 are (0,0,0);
  479. */
  480. double v_isortho(VECTOR * p1, VECTOR * p2)
  481. {
  482. return v_dot(p1, p2) == 0;
  483. }
  484. /*
  485. * Decide if P1 and P2 are parallel. If they are but have a diferent
  486. * direction, -1 is returned.
  487. */
  488. double v_ispara(VECTOR * p1, VECTOR * p2)
  489. {
  490. double dot, val, dif;
  491. dot = v_dot(p1, p2);
  492. val = v_val(p1);
  493. val *= v_val(p2);
  494. dif = fabs(dot - val);
  495. if (_is_zero(dif))
  496. return 1;
  497. dif = fabs(dot + val);
  498. if (_is_zero(dif))
  499. return -1;
  500. return 0;
  501. }
  502. /*
  503. * Decide if P1 and P2 have and angle alpha which: 0 < alpha < 90.0
  504. */
  505. double v_isacute(VECTOR * p1, VECTOR * p2)
  506. {
  507. return v_dot(p1, p2) > 0;
  508. }
  509. /*
  510. * Return the area spanned by the two vectors P1 and P2
  511. * Works only in 3D.
  512. */
  513. double v_area(VECTOR * p1, VECTOR * p2)
  514. {
  515. VECTOR p;
  516. return 0.5 * v_val(v_cross(&p, p1, p2));
  517. }