views:

145

answers:

3

I am trying to find out if a line defined by two points is greater than or equal to 90 degrees compared to the horizontal. Here is the code I used

bool moreThan90 = false;
double angle = Math.Atan((double)(EndingLocation.Y - Location.Y) / (double)(EndingLocation.X - Location.X));
if (angle >= Math.PI / 2.0 || angle <= -Math.PI / 2.0)
    moreThan90 = true;

Did I do this correctly or is there a better built in function in .Net that will find this?

EDIT -- Actually I messed up my question I ment to say 45 off of horizontal not 90. however the answers got me to a point where I can figure it out (really I just needed to be pointed at Atan2).

+3  A: 

You should call Math.Atan2, like this:

double angle = Math.Atan2(EndingLocation.Y - Location.Y, 
                          EndingLocation.X - Location.X);

if (Math.Abs(angle) >= Math.PI / 2.0)
    moreThan90 = true;
SLaks
+7  A: 

A line that is more than 90 degrees from the horizontal will have its EndLocation.x at a smaller x value than Location.x.

So you don't need all the atan nonsense, this should be enough:

if (EndingLocation.X < Location.X)
    moreThan90 = true;

EDIT:

Seems the OP meant 45 degrees not 90, which means that the above simplification no longer holds. For this it might be better to use atan2 (as Slaks pointed out) But in the spirit of not using tan:

if (Math.Abs(EndingLocation.X - Location.X) > Math.Abs(EndingLocation.Y - Location.Y) && 
    EndingLocation.X < Location.X)
    moreThan45 = true;

Note that you only need the 2nd check if you only want lines which point to the right

pheelicks
Wrong. This is more permissive than `Atan`
SLaks
@SLaks, but it is correct. Assuming that your using the horizontal as the X-Axis, and @Scott Chamberlain said he would rather not do floating point division if he didn't have to.
msarchet
Before downvoting, I suggest that you think - or draw a diagram. I am right
pheelicks
Seems reasonable to me given the question. (Perhaps the OP needs to reword it a bit)
GrahamS
I messed up my original question, I meant to say 45. you are correct for the 90 degree case. Edit your question so I can edit my vote
Scott Chamberlain
It seems correct to me with one little notice - depends on how you want to treat angles from 270 to 360 you may need to add ( || EndingLocation.Y < Location.Y).
a1ex07
@Scott Chamberlain: you mean you asked about 90 degrees (a very special case) and pheelicks answered, and you downvoted his answer because it didn't fit the question you *meant*?
Beta
@Beta, yes, so I am asking him to edit his question so i can change my down vote to a up vote.
Scott Chamberlain
@pheelicks, you beat me to my edit /salute
msarchet
Thanks for the division-less answer, and I do need to check all four quadrants. EDIT - I would like to note that this would not work if you could have negative x and y values but in the system I am using i all numbers will be > 0. so this will work perfectly.
Scott Chamberlain
@Scott: This will indeed work with negative numbers, and is exactly the answer I was going to give. It is simply moving the first point to the origin, and checking the second point if ABS(X) > ABS(Y), which tells you which side of the line y = x (or y = -x) the point is on.
BlueRaja - Danny Pflughoeft
You are right, I was doing the abs before the subtraction in the math in my head.
Scott Chamberlain
+3  A: 

I wouldn't imagine that there is a library method for finding the angle between the two vectors, you doing this correctly (the math is right) and a quick glance around msdn and google didn't provide me with anything. I would use SLaks' version of calling the Math.Atan method.

An interesting thing to note since you are using the 'horizontal' as your plane to determine if the angle is greater than 90 degrees. If endingLocation.x < Location.X your angle will always be 'greater' than 90 degrees, if you are measuring from the positive X-Axis.

Edit: Original question was changed to 45 degree check.

The section below is a discussion of how to do this without doing floating point division per a comment that the OP made.

To find out if you have a 45 degree angle we know a few things without actually having to call ATan on the points.

first the slope of a 45 degree angle is 1. So if

Math.Abs((EndLocation.y - location.y)/(EndLocation.X - Location.X)) > 1

You have an angle that is > 45 degrees, however as permutations of a 45 degree angle occur 4 times in a circle. We need to check a few things.

If EndLocation.X < Location.X then the angle is greater than 45 degrees. This represents all angles that are left of the Y Axis (90 - 270). To determine if the angle is greater than 45 degrees we only need to know if the absolute value of the slope is greater than 1. This will always be true for the following.

Math.Abs(EndLocation.Y - Location.Y) > Math.Abs(EndLocation.X - Location.X).

So with a if statement following something like

If (EndLocation.X < Location.X) OrElse (Math.Abs(EndLocation.Y - Location.Y) > Math.Abs(EndLocation.X - Location.X) Then AngleGreaterThan45 = True.

We can determine if the angle is greater than 45 degrees without the need to perform any floating point calculations.

msarchet