GS_util.c 7.9 KB

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