4
votes

So I'm trying to calculate the angle between three points. for example

a = [14, 140]
b = [13, 120]
c = [12, 130]
d = [11, 110]

|
|    c    a
|
|  d    b
|____________

say i want to calculate the angle between ABC i use the follow code

#create vectors
ba = a - b
bc = c- b
# calculate angle
cosine_angle = numpy.dot(ba,bc) / (numpy.linalg.norm(ba) * numpy.linalg.norm(bc))

angle = numpy.arccos(cosine_angle) 
pAngle = numpy.degrees(angle)

My script runs and the output angle works, my issue though is when i want to calculate BCD I want the angle on the outside not the inside so say instead of the angle being 120 degrees i want the angle 240. So i only want the anti-clockwise angles.

Not sure how to get this value, can anyone point me in the right direction?

*edit: in other terms i want to identify angles that are over 180 degrees anticlockwise

*edit2: the duplicate answer does not answer the question for me as i have not used alot of java so not sure how to code that in python

2
If you picture any two-line angle, you can always measure a kind of "interior" small angle, an "exterior" larger angle or - in the case of a straight line - two equal angles. Do you always want to return the smaller angle? Or are you actually looking to do this "clockwise" vs "anticlockwise"? I don't have numpy installed, but I wonder if you could effect this by passing your arguments in a different order?penitent_tangent
yeah only anticlockwise, or in other terms i want to identify any angles that are greater than 180 degrees in the anticlockwise directioncmca
The correct way is to use the atan2 function, as described in the duplicate answer. Replace a -> ba and b -> bc to directly apply the formula.Lutz Lehmann
cold you explain further?cmca

2 Answers

5
votes

Now using angular cosine distance to calculate the angle between two vectors is quite good, but in your case it might be better to use arc tangent as mentioned in the comments.

Now assuming you want to calculate the counterclockwise angle between BCD, you can do this by using the numpy's atan2 function. atan2(x, y) will give the angle between the origin point y to x.

import numpy as np

def calculate_angle(point_a, point_b):
    """ Calculate angle between two points """
    ang_a = np.arctan2(*point_a[::-1])
    ang_b = np.arctan2(*point_b[::-1])
    return np.rad2deg((ang_a - ang_b) % (2 * np.pi))

a = np.array([14, 140])
b = np.array([13, 120])
c = np.array([12, 130])
d = np.array([11, 110])

# create vectors
ba = a - b
bc = c - b
cd = d - c

# calculate angle
cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))

angle = np.arccos(cosine_angle)
inner_angle = np.degrees(angle)

print inner_angle  # 8.57299836361


# see how changing the direction changes the angle
print calculate_angle(bc, cd) # 188.572998364
print calculate_angle(cd, bc) # 171.427001636
0
votes

You are able to calculate the inner angle, but you want the reversed angle? why not just calculating 360 - angle