angle.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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 <stdio.h>
  25. #include <math.h>
  26. #include <grass/vector.h>
  27. static double d_atan2(double, double);
  28. float dig_calc_begin_angle(const struct line_pnts *points, double thresh)
  29. {
  30. double last_x;
  31. double last_y;
  32. const double *xptr;
  33. const double *yptr;
  34. int short_line;
  35. int i;
  36. int n_points;
  37. const double *xarray;
  38. const double *yarray;
  39. /* temporary way to set up use of struct line_pnts */
  40. n_points = points->n_points;
  41. xarray = points->x;
  42. yarray = points->y;
  43. last_x = *xarray;
  44. last_y = *yarray;
  45. xptr = xarray + 1;
  46. yptr = yarray + 1;
  47. /* check degenerate line */
  48. if (dig_line_degenerate(points) > 0)
  49. return ((float)-9.);
  50. short_line = 1;
  51. if (n_points != 2) {
  52. /* Search for next different coord. Note that in >= g5.7, threshold
  53. * is not used for build process. */
  54. /* 4.1 but do not use opposite node if there are other points */
  55. for (i = 1; i < n_points - 1; i++) {
  56. if ((thresh < fabs(*xptr - last_x)) ||
  57. (thresh < fabs(*yptr - last_y))) {
  58. short_line = 0;
  59. break;
  60. }
  61. xptr++;
  62. yptr++;
  63. }
  64. }
  65. if (short_line) {
  66. /* for 4.1 change this to take 1st point after node -dpg 12/92 */
  67. /* return ((float) d_atan2 (yarray[n_points - 1] - last_y, xarray[n_points - 1] - last_x)); */
  68. return ((float)d_atan2(yarray[1] - last_y, xarray[1] - last_x));
  69. }
  70. return ((float)d_atan2(*yptr - last_y, *xptr - last_x));
  71. } /* calc_begin_angle() */
  72. float dig_calc_end_angle(const struct line_pnts *points, double thresh)
  73. {
  74. double last_x;
  75. double last_y;
  76. const double *xptr;
  77. const double *yptr;
  78. int short_line;
  79. int i;
  80. int n_points;
  81. const double *xarray;
  82. const double *yarray;
  83. short_line = 1;
  84. xarray = points->x;
  85. yarray = points->y;
  86. n_points = points->n_points;
  87. /* check degenerate line */
  88. if (dig_line_degenerate(points) > 0)
  89. return ((float)-9.);
  90. last_x = *(xarray + n_points - 1);
  91. last_y = *(yarray + n_points - 1);
  92. xptr = xarray + n_points - 2;
  93. yptr = yarray + n_points - 2;
  94. if (n_points != 2) {
  95. /* Search for next different coord. Note that in >= g5.7, threshold
  96. * is not used for build process. */
  97. /* 4.1 but do not use opposite node if there are other points */
  98. for (i = n_points - 2; i > 0; i--) {
  99. if ((thresh < fabs(*xptr - last_x)) ||
  100. (thresh < fabs(*yptr - last_y))) {
  101. short_line = 0;
  102. break;
  103. }
  104. xptr--;
  105. yptr--;
  106. }
  107. }
  108. if (short_line) {
  109. /* updated for 4.1 to take next point away from node -dpg */
  110. /* return ((float) d_atan2 (yarray[0] - last_y, xarray[0] - last_x)); */
  111. return ((float)
  112. d_atan2(yarray[n_points - 2] - last_y,
  113. xarray[n_points - 2] - last_x));
  114. }
  115. return ((float)d_atan2(*yptr - last_y, *xptr - last_x));
  116. }
  117. int dig_is_line_degenerate(const struct line_pnts *points, double thresh)
  118. {
  119. double last_x;
  120. double last_y;
  121. const double *xptr;
  122. const double *yptr;
  123. int short_line;
  124. int i;
  125. int n_points;
  126. const double *xarray;
  127. const double *yarray;
  128. /* temporary way to set up use of struct line_pnts */
  129. n_points = points->n_points;
  130. xarray = points->x;
  131. yarray = points->y;
  132. last_x = *xarray;
  133. last_y = *yarray;
  134. xptr = xarray + 1;
  135. yptr = yarray + 1;
  136. short_line = 1;
  137. for (i = 1; i < n_points; i++) { /* Search for next different coord */
  138. if ((thresh < fabs(*xptr - last_x)) ||
  139. (thresh < fabs(*yptr - last_y))) {
  140. short_line = 0;
  141. break;
  142. }
  143. xptr++;
  144. yptr++;
  145. }
  146. if (short_line)
  147. return (1);
  148. return (0);
  149. }
  150. /* Check if line is degenerate (one point or more identical points)
  151. * Returns: 0 is not degenerate (but som points may be identical)
  152. * 1 one point
  153. * 2 more identical points
  154. */
  155. int dig_line_degenerate(const struct line_pnts *points)
  156. {
  157. int i, ident;
  158. int n_points;
  159. G_debug(5, "dig_line_degenerate()");
  160. /* temporary way to set up use of struct line_pnts */
  161. n_points = points->n_points;
  162. if (n_points == 1) {
  163. G_debug(5, " Line is degenerate (one points)");
  164. return 1;
  165. }
  166. /* check identical points (= one point) */
  167. ident = 1;
  168. for (i = 1; i < n_points; i++) {
  169. if (points->x[i] != points->x[i - 1] ||
  170. points->y[i] != points->y[i - 1]) {
  171. ident = 0;
  172. break;
  173. }
  174. }
  175. if (ident) {
  176. G_debug(5, " Line is degenerate (more points)");
  177. return 2;
  178. }
  179. return 0;
  180. }
  181. static double d_atan2(double y, double x)
  182. {
  183. if (y == 0.0 && x == 0.0)
  184. return (0.0);
  185. else
  186. return (atan2(y, x));
  187. }