GS_util.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /*!
  2. \file GS_util.c
  3. \brief OGSF library - loading and manipulating surfaces
  4. GRASS OpenGL gsurf OGSF Library
  5. (C) 1999-2008 by the GRASS Development Team
  6. This program is free software under the
  7. GNU General Public License (>=v2).
  8. Read the file COPYING that comes with GRASS
  9. for details.
  10. \author Bill Brown USACERL, GMSL/University of Illinois
  11. \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
  12. */
  13. #include <stdlib.h>
  14. #include <math.h>
  15. #include <string.h>
  16. #include <grass/gis.h>
  17. #include <grass/ogsf.h>
  18. /*!
  19. \brief Calculate distance between 2 coordinates
  20. Units is one of:
  21. - "meters",
  22. - "miles",
  23. - "kilometers",
  24. - "feet",
  25. - "yards",
  26. - "nmiles" (nautical miles),
  27. - "rods",
  28. - "inches",
  29. - "centimeters",
  30. - "millimeters",
  31. - "micron",
  32. - "nanometers",
  33. - "cubits",
  34. - "hands",
  35. - "furlongs",
  36. - "chains"
  37. Default is meters.
  38. \param from starting point
  39. \param to ending point
  40. \param units map units
  41. \return distance between two geographic coordinates in current projection
  42. */
  43. double GS_geodistance(double *from, double *to, const char *units)
  44. {
  45. double meters;
  46. meters = Gs_distance(from, to);
  47. if (!units) {
  48. return (meters);
  49. }
  50. if (strcmp(units, "meters") == 0) {
  51. return (meters);
  52. }
  53. if (strcmp(units, "miles") == 0) {
  54. return (meters * .0006213712);
  55. }
  56. if (strcmp(units, "kilometers") == 0) {
  57. return (meters * .001);
  58. }
  59. if (strcmp(units, "feet") == 0) {
  60. return (meters * 3.280840);
  61. }
  62. if (strcmp(units, "yards") == 0) {
  63. return (meters * 1.093613);
  64. }
  65. if (strcmp(units, "rods") == 0) {
  66. return (meters * .1988388);
  67. }
  68. if (strcmp(units, "inches") == 0) {
  69. return (meters * 39.37008);
  70. }
  71. if (strcmp(units, "centimeters") == 0) {
  72. return (meters * 100.0);
  73. }
  74. if (strcmp(units, "millimeters") == 0) {
  75. return (meters * 1000.0);
  76. }
  77. if (strcmp(units, "micron") == 0) {
  78. return (meters * 1000000.0);
  79. }
  80. if (strcmp(units, "nanometers") == 0) {
  81. return (meters * 1000000000.0);
  82. }
  83. if (strcmp(units, "cubits") == 0) {
  84. return (meters * 2.187227);
  85. }
  86. if (strcmp(units, "hands") == 0) {
  87. return (meters * 9.842520);
  88. }
  89. if (strcmp(units, "furlongs") == 0) {
  90. return (meters * .004970970);
  91. }
  92. if (strcmp(units, "nmiles") == 0) {
  93. /* nautical miles */
  94. return (meters * .0005399568);
  95. }
  96. if (strcmp(units, "chains") == 0) {
  97. return (meters * .0497097);
  98. }
  99. return (meters);
  100. }
  101. /*!
  102. \brief Calculate distance
  103. \param from 'from' point (X,Y,Z)
  104. \param to 'to' point (X,Y,Z)
  105. \return distance
  106. */
  107. float GS_distance(float *from, float *to)
  108. {
  109. float x, y, z;
  110. x = from[X] - to[X];
  111. y = from[Y] - to[Y];
  112. z = from[Z] - to[Z];
  113. return (float)sqrt(x * x + y * y + z * z);
  114. }
  115. /*!
  116. \brief Calculate distance in plane
  117. \param from 'from' point (X,Y)
  118. \param to 'to' point (X,Y)
  119. \return distance
  120. */
  121. float GS_P2distance(float *from, float *to)
  122. {
  123. float x, y;
  124. x = from[X] - to[X];
  125. y = from[Y] - to[Y];
  126. return (float)sqrt(x * x + y * y);
  127. }
  128. /*!
  129. \brief Copy vector values
  130. v1 = v2
  131. \param[out] v1 first vector
  132. \param v2 second vector
  133. */
  134. void GS_v3eq(float *v1, float *v2)
  135. {
  136. v1[X] = v2[X];
  137. v1[Y] = v2[Y];
  138. v1[Z] = v2[Z];
  139. return;
  140. }
  141. /*!
  142. \brief Sum vectors
  143. v1 += v2
  144. \param[in,out] v1 first vector
  145. \param v2 second vector
  146. */
  147. void GS_v3add(float *v1, float *v2)
  148. {
  149. v1[X] += v2[X];
  150. v1[Y] += v2[Y];
  151. v1[Z] += v2[Z];
  152. return;
  153. }
  154. /*!
  155. \brief Subtract vectors
  156. v1 -= v2
  157. \param[in,out] v1 first vector
  158. \param v2 second vector
  159. */
  160. void GS_v3sub(float *v1, float *v2)
  161. {
  162. v1[X] -= v2[X];
  163. v1[Y] -= v2[Y];
  164. v1[Z] -= v2[Z];
  165. return;
  166. }
  167. /*!
  168. \brief Multiple vectors
  169. v1 *= k
  170. \param[in,out] v1 vector
  171. \param k multiplicator
  172. */
  173. void GS_v3mult(float *v1, float k)
  174. {
  175. v1[X] *= k;
  176. v1[Y] *= k;
  177. v1[Z] *= k;
  178. return;
  179. }
  180. /*!
  181. \brief Change v1 so that it is a unit vector (2D)
  182. \param[in,out] v1 vector
  183. \return 0 if magnitude of v1 is zero
  184. \return 1 if magnitude of v1 > 0
  185. */
  186. int GS_v3norm(float *v1)
  187. {
  188. float n;
  189. n = sqrt(v1[X] * v1[X] + v1[Y] * v1[Y] + v1[Z] * v1[Z]);
  190. if (n == 0.0) {
  191. return (0);
  192. }
  193. v1[X] /= n;
  194. v1[Y] /= n;
  195. v1[Z] /= n;
  196. return (1);
  197. }
  198. /*!
  199. \brief Change v1 so that it is a unit vector (3D)
  200. \param[in,out] v1 vector
  201. \return 0 if magnitude of v1 is zero
  202. \return 1 if magnitude of v1 > 0
  203. */
  204. int GS_v2norm(float *v1)
  205. {
  206. float n;
  207. n = sqrt(v1[X] * v1[X] + v1[Y] * v1[Y]);
  208. if (n == 0.0) {
  209. return (0);
  210. }
  211. v1[X] /= n;
  212. v1[Y] /= n;
  213. return (1);
  214. }
  215. /*!
  216. \brief Changes v1 so that it is a unit vector
  217. \param dv1 vector
  218. \return 0 if magnitude of dv1 is zero
  219. \return 1 if magnitude of dv1 > 0
  220. */
  221. int GS_dv3norm(double *dv1)
  222. {
  223. double n;
  224. n = sqrt(dv1[X] * dv1[X] + dv1[Y] * dv1[Y] + dv1[Z] * dv1[Z]);
  225. if (n == 0.0) {
  226. return (0);
  227. }
  228. dv1[X] /= n;
  229. dv1[Y] /= n;
  230. dv1[Z] /= n;
  231. return (1);
  232. }
  233. /*!
  234. \brief Change v2 so that v1v2 is a unit vector
  235. \param v1 first vector
  236. \param v2[in,out] second vector
  237. \return 0 if magnitude of dx is zero
  238. \return 1 if magnitude of dx > 0
  239. */
  240. int GS_v3normalize(float *v1, float *v2)
  241. {
  242. float n, dx, dy, dz;
  243. dx = v2[X] - v1[X];
  244. dy = v2[Y] - v1[Y];
  245. dz = v2[Z] - v1[Z];
  246. n = sqrt(dx * dx + dy * dy + dz * dz);
  247. if (n == 0.0) {
  248. return (0);
  249. }
  250. v2[X] = v1[X] + dx / n;
  251. v2[Y] = v1[Y] + dy / n;
  252. v2[Z] = v1[Z] + dz / n;
  253. return (1);
  254. }
  255. /*!
  256. \brief Get a normalized direction from v1 to v2, store in v3
  257. \param v1 first vector
  258. \param v2 second vector
  259. \param[out] v3 output vector
  260. \return 0 if magnitude of dx is zero
  261. \return 1 if magnitude of dx > 0
  262. */
  263. int GS_v3dir(float *v1, float *v2, float *v3)
  264. {
  265. float n, dx, dy, dz;
  266. dx = v2[X] - v1[X];
  267. dy = v2[Y] - v1[Y];
  268. dz = v2[Z] - v1[Z];
  269. n = sqrt(dx * dx + dy * dy + dz * dz);
  270. if (n == 0.0) {
  271. v3[X] = v3[Y] = v3[Z] = 0.0;
  272. return (0);
  273. }
  274. v3[X] = dx / n;
  275. v3[Y] = dy / n;
  276. v3[Z] = dz / n;
  277. return (1);
  278. }
  279. /*!
  280. \brief Get a normalized direction from v1 to v2, store in v3 (2D)
  281. \param v1 first vector
  282. \param v2 second vector
  283. \param[out] v3 output vector
  284. \return 0 if magnitude of dx is zero
  285. \return 1 if magnitude of dx > 0
  286. */
  287. void GS_v2dir(float *v1, float *v2, float *v3)
  288. {
  289. float n, dx, dy;
  290. dx = v2[X] - v1[X];
  291. dy = v2[Y] - v1[Y];
  292. n = sqrt(dx * dx + dy * dy);
  293. v3[X] = dx / n;
  294. v3[Y] = dy / n;
  295. return;
  296. }
  297. /*!
  298. \brief Get the cross product v3 = v1 cross v2
  299. \param v1 first vector
  300. \param v2 second vector
  301. \param[out] v3 output vector
  302. */
  303. void GS_v3cross(float *v1, float *v2, float *v3)
  304. {
  305. v3[X] = (v1[Y] * v2[Z]) - (v1[Z] * v2[Y]);
  306. v3[Y] = (v1[Z] * v2[X]) - (v1[X] * v2[Z]);
  307. v3[Z] = (v1[X] * v2[Y]) - (v1[Y] * v2[X]);
  308. return;
  309. }
  310. /*!
  311. \brief Magnitude of vector
  312. \param v1 vector
  313. \param[out] mag magnitude value
  314. */
  315. void GS_v3mag(float *v1, float *mag)
  316. {
  317. *mag = sqrt(v1[X] * v1[X] + v1[Y] * v1[Y] + v1[Z] * v1[Z]);
  318. return;
  319. }
  320. /*!
  321. \brief ADD
  322. Initialize by calling with a number nhist to represent number of
  323. previous entrys to check, then call with zero as nhist
  324. \param p1 first point
  325. \param p2 second point
  326. \param nhist ?
  327. \return -1 on error
  328. \return -2
  329. \return 1
  330. \return 9
  331. */
  332. int GS_coordpair_repeats(float *p1, float *p2, int nhist)
  333. {
  334. static float *entrys = NULL;
  335. static int next = 0;
  336. static int len = 0;
  337. int i;
  338. if (nhist) {
  339. if (entrys) {
  340. G_free(entrys);
  341. }
  342. entrys = (float *)G_malloc(4 * nhist * sizeof(float));
  343. if (!entrys)
  344. return (-1);
  345. len = nhist;
  346. next = 0;
  347. }
  348. if (!len) {
  349. return (-2);
  350. }
  351. for (i = 0; i < next; i += 4) {
  352. if (entrys[i] == p1[0] && entrys[i + 1] == p1[1]
  353. && entrys[i + 2] == p2[0] && entrys[i + 3] == p2[1]) {
  354. return (1);
  355. }
  356. }
  357. if (len == next / 4) {
  358. next = 0;
  359. }
  360. entrys[next] = p1[0];
  361. entrys[next + 1] = p1[1];
  362. entrys[next + 2] = p2[0];
  363. entrys[next + 3] = p2[1];
  364. next += 4;
  365. return (0);
  366. }