I am trying to calculate the angle between two lines in python. I searched the internet and found the equation on how to do it. But I don't always get accurate result. Some of the results are clearly false when other seems correct. My code is given below:
def angle(pt1,pt2):
m1 = (pt1.getY() - pt1.getY())/1
m2 = (pt2.getY() - pt1.getY())/(pt2.getX()-pt1.getX())
tnAngle = (m1-m2)/(1+(m1*m2))
return math.atan(tnAngle)
def calculate(pt,ls):
i=2
for x in ls:
pt2 = point(x,i)
i=i+1
ang = angle(pt,pt2)*180/math.pi
ang = ang * (-1)
print ang
pt = point(3,1)
ls = [1,7,0,4,9,6,150]
calculate(pt,ls)
the result it produces is :
45.0
0.0
45.0
-75.9637565321
0.0
-63.4349488229
0.0
The problem is that I don't understand why the second result, fifth and the last one are zeroed they intersect since they share a point and the other point in not duplicated since the value in the array is different.
Your angle formula will fail if
pt2.getX() == pt1.getX()
(that is, if pt1 and pt2 lie on a vertical line) because you can not divide by zero. (m2
, the slope, would be infinite.)
Also
m1 = (pt1.getY() - pt1.getY())/1
will always be zero. So at the very least, your formula could be simplified to the arctan of the slope. However, I wouldn't bother since the formula does not work for all possible points.
Instead, a more robust method (indeed, the standard method) for calculating the angle between two vectors (directed line segments) is to use the dot product formula:
where if a = (x1, y1)
, b = (x2, y2)
, then <a,b>
equals x1*x2 + y1*y2
, and
||a||
is the length of vector a
, i.e. sqrt(x1**2 + y1**2)
.
import math
def angle(vector1, vector2):
x1, y1 = vector1
x2, y2 = vector2
inner_product = x1*x2 + y1*y2
len1 = math.hypot(x1, y1)
len2 = math.hypot(x2, y2)
return math.acos(inner_product/(len1*len2))
def calculate(pt, ls):
i = 2
for x in ls:
pt2 = (x, i)
i += 1
ang = math.degrees(angle(pt, pt2))
ang = ang * (-1)
print(ang)
pt = (3, 1)
ls = [1,7,0,4,9,6,150]
calculate(pt, ls)
Here is what I ended up using, all using numpy and the range is between -𝛑 to 𝛑
import numpy as np
def get_angle(p0, p1=np.array([0,0]), p2=None):
''' compute angle (in degrees) for p0p1p2 corner
Inputs:
p0,p1,p2 - points in the form of [x,y]
'''
if p2 is None:
p2 = p1 + np.array([1, 0])
v0 = np.array(p0) - np.array(p1)
v1 = np.array(p2) - np.array(p1)
angle = np.math.atan2(np.linalg.det([v0,v1]),np.dot(v0,v1))
return np.degrees(angle)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With