GRASS Programmer's Manual
6.4.1(2011)
|
00001 /* 00002 **************************************************************************** 00003 * 00004 * MODULE: Vector library 00005 * 00006 * AUTHOR(S): Original author CERL, probably Dave Gerdes. 00007 * Update to GRASS 5.7 Radim Blazek. 00008 * 00009 * PURPOSE: Lower level functions for reading/writing/manipulating vectors. 00010 * 00011 * COPYRIGHT: (C) 2001 by the GRASS Development Team 00012 * 00013 * This program is free software under the GNU General Public 00014 * License (>=v2). Read the file COPYING that comes with GRASS 00015 * for details. 00016 * 00017 *****************************************************************************/ 00018 /* 00019 * functions - calc_begin_angle(), and calc_end_angle() 00020 * used to calculate the angle of a line to a node. 00021 * returns - (float)angle (-PI ... +PI) 00022 * returns - (float)(-9) if only 1 point or more points but identical 00023 */ 00024 00025 #include <stdio.h> 00026 #include <math.h> 00027 #include <grass/Vect.h> 00028 00029 static double d_atan2(double, double); 00030 00031 float dig_calc_begin_angle(struct line_pnts *points, double thresh) 00032 { 00033 double last_x; 00034 double last_y; 00035 double *xptr; 00036 double *yptr; 00037 int short_line; 00038 int i; 00039 int n_points; 00040 double *xarray; 00041 double *yarray; 00042 00043 /* temporary way to set up use of struct line_pnts */ 00044 n_points = points->n_points; 00045 xarray = points->x; 00046 yarray = points->y; 00047 00048 last_x = *xarray; 00049 last_y = *yarray; 00050 xptr = xarray + 1; 00051 yptr = yarray + 1; 00052 00053 /* check degenerate line */ 00054 if (dig_line_degenerate(points) > 0) 00055 return ((float)-9.); 00056 00057 short_line = 1; 00058 if (n_points != 2) { 00059 /* Search for next different coord. Note that in >= g5.7, threshold 00060 * is not used for build process. */ 00061 /* 4.1 but do not use opposite node if there are other points */ 00062 for (i = 1; i < n_points - 1; i++) { 00063 if ((thresh < fabs(*xptr - last_x)) || 00064 (thresh < fabs(*yptr - last_y))) { 00065 short_line = 0; 00066 break; 00067 } 00068 xptr++; 00069 yptr++; 00070 } 00071 } 00072 00073 if (short_line) { 00074 /* for 4.1 change this to take 1st point after node -dpg 12/92 */ 00075 /* return ((float) d_atan2 (yarray[n_points - 1] - last_y, xarray[n_points - 1] - last_x)); */ 00076 return ((float)d_atan2(yarray[1] - last_y, xarray[1] - last_x)); 00077 } 00078 00079 return ((float)d_atan2(*yptr - last_y, *xptr - last_x)); 00080 } /* calc_begin_angle() */ 00081 00082 float dig_calc_end_angle(struct line_pnts *points, double thresh) 00083 { 00084 double last_x; 00085 double last_y; 00086 double *xptr; 00087 double *yptr; 00088 int short_line; 00089 int i; 00090 int n_points; 00091 double *xarray; 00092 double *yarray; 00093 00094 short_line = 1; 00095 00096 xarray = points->x; 00097 yarray = points->y; 00098 n_points = points->n_points; 00099 00100 /* check degenerate line */ 00101 if (dig_line_degenerate(points) > 0) 00102 return ((float)-9.); 00103 00104 last_x = *(xarray + n_points - 1); 00105 last_y = *(yarray + n_points - 1); 00106 xptr = xarray + n_points - 2; 00107 yptr = yarray + n_points - 2; 00108 00109 if (n_points != 2) { 00110 /* Search for next different coord. Note that in >= g5.7, threshold 00111 * is not used for build process. */ 00112 /* 4.1 but do not use opposite node if there are other points */ 00113 for (i = n_points - 2; i > 0; i--) { 00114 if ((thresh < fabs(*xptr - last_x)) || 00115 (thresh < fabs(*yptr - last_y))) { 00116 short_line = 0; 00117 break; 00118 } 00119 xptr--; 00120 yptr--; 00121 } 00122 } 00123 00124 if (short_line) { 00125 /* updated for 4.1 to take next point away from node -dpg */ 00126 /* return ((float) d_atan2 (yarray[0] - last_y, xarray[0] - last_x)); */ 00127 return ((float) 00128 d_atan2(yarray[n_points - 2] - last_y, 00129 xarray[n_points - 2] - last_x)); 00130 } 00131 00132 return ((float)d_atan2(*yptr - last_y, *xptr - last_x)); 00133 } 00134 00135 int dig_is_line_degenerate(struct line_pnts *points, double thresh) 00136 { 00137 double last_x; 00138 double last_y; 00139 double *xptr; 00140 double *yptr; 00141 int short_line; 00142 int i; 00143 int n_points; 00144 double *xarray; 00145 double *yarray; 00146 00147 /* temporary way to set up use of struct line_pnts */ 00148 n_points = points->n_points; 00149 xarray = points->x; 00150 yarray = points->y; 00151 00152 last_x = *xarray; 00153 last_y = *yarray; 00154 xptr = xarray + 1; 00155 yptr = yarray + 1; 00156 00157 short_line = 1; 00158 for (i = 1; i < n_points; i++) { /* Search for next different coord */ 00159 if ((thresh < fabs(*xptr - last_x)) || 00160 (thresh < fabs(*yptr - last_y))) { 00161 short_line = 0; 00162 break; 00163 } 00164 xptr++; 00165 yptr++; 00166 } 00167 00168 if (short_line) 00169 return (1); 00170 00171 return (0); 00172 00173 } 00174 00175 /* Check if line is degenerate (one point or more identical points) 00176 * Returns: 0 is not degenerate (but som points may be identical) 00177 * 1 one point 00178 * 2 more identical points 00179 */ 00180 int dig_line_degenerate(struct line_pnts *points) 00181 { 00182 int i, ident; 00183 int n_points; 00184 00185 G_debug(5, "dig_line_degenerate()"); 00186 /* temporary way to set up use of struct line_pnts */ 00187 n_points = points->n_points; 00188 00189 if (n_points == 1) { 00190 G_debug(5, " Line is degenerate (one points)"); 00191 return 1; 00192 } 00193 00194 /* check identical points (= one point) */ 00195 ident = 1; 00196 for (i = 1; i < n_points; i++) { 00197 if (points->x[i] != points->x[i - 1] || 00198 points->y[i] != points->y[i - 1]) { 00199 ident = 0; 00200 break; 00201 } 00202 } 00203 00204 if (ident) { 00205 G_debug(5, " Line is degenerate (more points)"); 00206 return 2; 00207 } 00208 00209 return 0; 00210 } 00211 00212 static double d_atan2(double y, double x) 00213 { 00214 if (y == 0.0 && x == 0.0) 00215 return (0.0); 00216 else 00217 return (atan2(y, x)); 00218 }