angle.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. ****************************************************************************
  3. *
  4. * MODULE: Vector library
  5. *
  6. * AUTHOR(S): Original author CERL, probably Dave Gerdes.
  7. * Update to GRASS 5.7 Radim Blazek.
  8. *
  9. * PURPOSE: Lower level functions for reading/writing/manipulating vectors.
  10. *
  11. * COPYRIGHT: (C) 2001 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *
  17. *****************************************************************************/
  18. /*
  19. * functions - calc_begin_angle(), and calc_end_angle()
  20. * used to calculate the angle of a line to a node.
  21. * returns - (float)angle (-PI ... +PI)
  22. * returns - (float)(-9) if only 1 point or more points but identical
  23. */
  24. #include <grass/config.h>
  25. #include <stdio.h>
  26. #include <math.h>
  27. #include <grass/vector.h>
  28. static double d_atan2(double, double);
  29. float dig_calc_begin_angle(const struct line_pnts *points, double thresh)
  30. {
  31. double last_x;
  32. double last_y;
  33. const double *xptr;
  34. const double *yptr;
  35. int short_line;
  36. int i;
  37. int n_points;
  38. const double *xarray;
  39. const double *yarray;
  40. /* temporary way to set up use of struct line_pnts */
  41. n_points = points->n_points;
  42. xarray = points->x;
  43. yarray = points->y;
  44. last_x = *xarray;
  45. last_y = *yarray;
  46. xptr = xarray + 1;
  47. yptr = yarray + 1;
  48. /* check degenerate line */
  49. if (dig_line_degenerate(points) > 0)
  50. return ((float)-9.);
  51. short_line = 1;
  52. if (n_points != 2) {
  53. /* Search for next different coord. Note that in >= g5.7, threshold
  54. * is not used for build process. */
  55. /* 4.1 but do not use opposite node if there are other points */
  56. for (i = 1; i < n_points - 1; i++) {
  57. if ((thresh < fabs(*xptr - last_x)) ||
  58. (thresh < fabs(*yptr - last_y))) {
  59. short_line = 0;
  60. break;
  61. }
  62. xptr++;
  63. yptr++;
  64. }
  65. }
  66. if (short_line) {
  67. /* for 4.1 change this to take 1st point after node -dpg 12/92 */
  68. /* return ((float) d_atan2 (yarray[n_points - 1] - last_y, xarray[n_points - 1] - last_x)); */
  69. return ((float)d_atan2(yarray[1] - last_y, xarray[1] - last_x));
  70. }
  71. return ((float)d_atan2(*yptr - last_y, *xptr - last_x));
  72. } /* calc_begin_angle() */
  73. float dig_calc_end_angle(const struct line_pnts *points, double thresh)
  74. {
  75. double last_x;
  76. double last_y;
  77. const double *xptr;
  78. const double *yptr;
  79. int short_line;
  80. int i;
  81. int n_points;
  82. const double *xarray;
  83. const double *yarray;
  84. short_line = 1;
  85. xarray = points->x;
  86. yarray = points->y;
  87. n_points = points->n_points;
  88. /* check degenerate line */
  89. if (dig_line_degenerate(points) > 0)
  90. return ((float)-9.);
  91. last_x = *(xarray + n_points - 1);
  92. last_y = *(yarray + n_points - 1);
  93. xptr = xarray + n_points - 2;
  94. yptr = yarray + n_points - 2;
  95. if (n_points != 2) {
  96. /* Search for next different coord. Note that in >= g5.7, threshold
  97. * is not used for build process. */
  98. /* 4.1 but do not use opposite node if there are other points */
  99. for (i = n_points - 2; i > 0; i--) {
  100. if ((thresh < fabs(*xptr - last_x)) ||
  101. (thresh < fabs(*yptr - last_y))) {
  102. short_line = 0;
  103. break;
  104. }
  105. xptr--;
  106. yptr--;
  107. }
  108. }
  109. if (short_line) {
  110. /* updated for 4.1 to take next point away from node -dpg */
  111. /* return ((float) d_atan2 (yarray[0] - last_y, xarray[0] - last_x)); */
  112. return ((float)
  113. d_atan2(yarray[n_points - 2] - last_y,
  114. xarray[n_points - 2] - last_x));
  115. }
  116. return ((float)d_atan2(*yptr - last_y, *xptr - last_x));
  117. }
  118. int dig_is_line_degenerate(const struct line_pnts *points, double thresh)
  119. {
  120. double last_x;
  121. double last_y;
  122. const double *xptr;
  123. const double *yptr;
  124. int short_line;
  125. int i;
  126. int n_points;
  127. const double *xarray;
  128. const double *yarray;
  129. /* temporary way to set up use of struct line_pnts */
  130. n_points = points->n_points;
  131. xarray = points->x;
  132. yarray = points->y;
  133. last_x = *xarray;
  134. last_y = *yarray;
  135. xptr = xarray + 1;
  136. yptr = yarray + 1;
  137. short_line = 1;
  138. for (i = 1; i < n_points; i++) { /* Search for next different coord */
  139. if ((thresh < fabs(*xptr - last_x)) ||
  140. (thresh < fabs(*yptr - last_y))) {
  141. short_line = 0;
  142. break;
  143. }
  144. xptr++;
  145. yptr++;
  146. }
  147. if (short_line)
  148. return (1);
  149. return (0);
  150. }
  151. /* Check if line is degenerate (one point or more identical points)
  152. * Returns: 0 is not degenerate (but som points may be identical)
  153. * 1 one point
  154. * 2 more identical points
  155. */
  156. int dig_line_degenerate(const struct line_pnts *points)
  157. {
  158. int i, ident;
  159. int n_points;
  160. G_debug(5, "dig_line_degenerate()");
  161. /* temporary way to set up use of struct line_pnts */
  162. n_points = points->n_points;
  163. if (n_points == 1) {
  164. G_debug(5, " Line is degenerate (one points)");
  165. return 1;
  166. }
  167. /* check identical points (= one point) */
  168. ident = 1;
  169. for (i = 1; i < n_points; i++) {
  170. if (points->x[i] != points->x[i - 1] ||
  171. points->y[i] != points->y[i - 1]) {
  172. ident = 0;
  173. break;
  174. }
  175. }
  176. if (ident) {
  177. G_debug(5, " Line is degenerate (more points)");
  178. return 2;
  179. }
  180. return 0;
  181. }
  182. static double d_atan2(double y, double x)
  183. {
  184. if (y == 0.0 && x == 0.0)
  185. return (0.0);
  186. else
  187. return (atan2(y, x));
  188. }