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