GRASS GIS 7 Programmer's Manual  7.5.svn(2017)-r71769
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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, xarray[n_points - 1] - last_x)); */
76  return ((float)d_atan2(yarray[1] - last_y, xarray[1] - last_x));
77  }
78 
79  return ((float)d_atan2(*yptr - last_y, *xptr - last_x));
80 } /* calc_begin_angle() */
81 
82 float dig_calc_end_angle(const struct line_pnts *points, double thresh)
83 {
84  double last_x;
85  double last_y;
86  const double *xptr;
87  const double *yptr;
88  int short_line;
89  int i;
90  int n_points;
91  const double *xarray;
92  const double *yarray;
93 
94  short_line = 1;
95 
96  xarray = points->x;
97  yarray = points->y;
98  n_points = points->n_points;
99 
100  /* check degenerate line */
101  if (dig_line_degenerate(points) > 0)
102  return ((float)-9.);
103 
104  last_x = *(xarray + n_points - 1);
105  last_y = *(yarray + n_points - 1);
106  xptr = xarray + n_points - 2;
107  yptr = yarray + n_points - 2;
108 
109  if (n_points != 2) {
110  /* Search for next different coord. Note that in >= g5.7, threshold
111  * is not used for build process. */
112  /* 4.1 but do not use opposite node if there are other points */
113  for (i = n_points - 2; i > 0; i--) {
114  if ((thresh < fabs(*xptr - last_x)) ||
115  (thresh < fabs(*yptr - last_y))) {
116  short_line = 0;
117  break;
118  }
119  xptr--;
120  yptr--;
121  }
122  }
123 
124  if (short_line) {
125  /* updated for 4.1 to take next point away from node -dpg */
126  /* return ((float) d_atan2 (yarray[0] - last_y, xarray[0] - last_x)); */
127  return ((float)
128  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 
175 /* Check if line is degenerate (one point or more identical points)
176  * Returns: 0 is not degenerate (but som points may be identical)
177  * 1 one point
178  * 2 more identical points
179  */
180 int dig_line_degenerate(const struct line_pnts *points)
181 {
182  int i, ident;
183  int n_points;
184 
185  G_debug(5, "dig_line_degenerate()");
186  /* temporary way to set up use of struct line_pnts */
187  n_points = points->n_points;
188 
189  if (n_points == 1) {
190  G_debug(5, " Line is degenerate (one points)");
191  return 1;
192  }
193 
194  /* check identical points (= one point) */
195  ident = 1;
196  for (i = 1; i < n_points; i++) {
197  if (points->x[i] != points->x[i - 1] ||
198  points->y[i] != points->y[i - 1]) {
199  ident = 0;
200  break;
201  }
202  }
203 
204  if (ident) {
205  G_debug(5, " Line is degenerate (more points)");
206  return 2;
207  }
208 
209  return 0;
210 }
211 
212 static double d_atan2(double y, double x)
213 {
214  if (y == 0.0 && x == 0.0)
215  return (0.0);
216  else
217  return (atan2(y, x));
218 }
int n_points
Number of points.
Definition: dig_structs.h:1692
float dig_calc_end_angle(const struct line_pnts *, double)
Definition: angle.c:82
#define x
double * x
Array of X coordinates.
Definition: dig_structs.h:1680
Feature geometry info - coordinates.
Definition: dig_structs.h:1675
float dig_calc_begin_angle(const struct line_pnts *, double)
Definition: angle.c:31
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
double * y
Array of Y coordinates.
Definition: dig_structs.h:1684
int dig_line_degenerate(const struct line_pnts *)
Definition: angle.c:180
int dig_is_line_degenerate(const struct line_pnts *, double)
Definition: angle.c:135