[GRASS5] Angle of Line Function?

Eric G. Miller egm2 at jps.net
Sat Mar 10 18:12:01 EST 2001


On Sat, Mar 10, 2001 at 02:04:23PM -0800, Eric G. Miller wrote:
> On Sat, Mar 10, 2001 at 04:25:20PM -0400, Bob Covill wrote:
> > Jeshua Lacock wrote:
> > 
> > > Greetings,
> > >
> > > I would greatly appreciate any help with developing a simple function
> > > that returns the angle (in degrees) of a line when given two points
> > > (x1, y1 and x2, y2).
> > >
> > > Embarrassingly I have spent days trying to figure this out (that's
> > > what I get for using the teachers edition of geometry in high
> > > school!!).  ;->
> > >
> > > I have ran across a function on the web, but somehow it seems really off:
> > >      angle = (((Atan((northingDifference/eastingDifference)))*180)/PI)
> 
> Arctan() will give you an acute angle. You would need to know the
> quadrant the line is in (assuming the first point as the origin) to add
> a correction factor.
> 
> Assuming (0 == North, 90 == East, etc...):
> 
> // Sorta code...
> 
> dy = (y2 - y1);
> dx = (x2 - x1);
> 
> if (dy > 0.0 && dx > 0.0) {quadadjust = 0.0;}
> else if (dy > 0.0 && dx < 0.0) {quadadjust = 360.0;}
> else if (dy < 0.0 && dx > 0.0) {quadadjust = 180.0;}
> else if (dy < 0.0 && dx < 0.0) {quadadjust = 180.0;}
> else {
>   if (dx == 0.0) {slope = (dy > 0.0) ? 0.0 : 180.0;}
>   else if (dy == 0.0) {slope = (dx > 0.0) ? 90.0 : 270.0;}
>   else {/* huh? */}
>   return slope;
> }
> 
> slope = ((atan(dy/dx) * 180) / M_PI) + quadadjust;
> return slope;
> 
> // End.
> 
> Note, I haven't really checked the above...  And floating point numbers
> can be weird in comparisons, so maybe an EPSILON is needed...
> 
> I understand there are better ways to do this than using atan() which
> can be expensive...

Sorry, the above is *not correct*.
I think the below would work...

dy = y2 - y1;
dx = x2 - x1;

assert (!(dx == 0.0 && dy == 0.0));

if (dx == 0.0)  /* Special case, vertical line */
{
  if (dy > 0.0)
    return 0.0;
  else
    return 180.0;
}
if (dy == 0.0) /* Special case, horizontal line */
{
  if (dx > 0.0)
    return 90.0;
  else
    return 270.0;
}
if (dx > 0.0)
  return 90.0 - atan(dy/dx) * (180 / M_PI);
else if (dx < 0.0)
  return 270.0 - atan(dy/dx) * (180 / M_PI);

exit (EXIT_FAILURE);

-- 
Eric G. Miller <egm2 at jps.net>

---------------------------------------- 
If you want to unsubscribe from GRASS Development Team mailing list write to:
minordomo at geog.uni-hannover.de with
subject 'unsubscribe grass5'



More information about the grass-dev mailing list