GRASS 8 Programmer's Manual 8.6.0dev(2026)-ddeab64dbf
Loading...
Searching...
No Matches
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
29static double d_atan2(double, double);
30
31float 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
83float 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
135int 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 */
179int 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
211static 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.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
int n_points
Number of points.