angle.c

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

Generated on Sun Apr 6 17:32:44 2008 for GRASS by  doxygen 1.5.5