GRASS Programmer's Manual  6.4.1(2011)
angle.c
Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines