I currently have a series of lines drawn in a football pitch, each one formed by an X and Y point. These lines are the passes of a player and I want to see if it is a backward pass, forward pass, lateral pass depending on the angle of the slope with the X axis.
Axis Y is inverted(Positive values going down)
I have tried several ideas like arctan from numpy, from math, several calculations but I can't get the angle correctly. Results are not making any sense.
At the moment, the only certainty is the correct calculation of the slope of each line.
df['Slope'] = np.where(df['X'] == df['X2'], 0,
np.where((df['Y'] == df['Y2']), 0,
-df['Y2'] df['Y'])/ (df['X2'] - df['X']))
df['Radians'] = np.arctan(df['Slope'].astype(float))
df['Degrees'] = np.degrees(df['Radians']) 60
Some numbers and possibly angle expected:
A(40,48) and B(27,70): 210-230ª Actual result: 60º
A(27,74) and B(9,52) : 130-140º Actual result: 310º
A(9,64) and B(11,45) : 75-80º Actual result: 84º seems OK
CodePudding user response:
Here is a standard-library solution which seems to work. The same principle can be used with numpy.
Key points:
Use
atan2
to get an answer in the right quadrantSince Y axis points "down", negate Y values
Use
% 360
to "fold" result to [0, 360] range.
(I have to write something here to get the formatting right... why?)
from math import degrees, atan2
def angle(x1, y1, x2, y2):
# (-a)-(-b) = -a b
return degrees(atan2(-y2 y1, x2-x1)) % 360
print(angle(40, 48, 27, 70)) # 239
print(angle(27, 74, 9, 52)) # 129
print(angle(9, 64, 11, 45)) # 84