39

I have a triangle (A, B, C) and am trying to find the angle between each pair of the three points.

The problem is that the algorithms I can find online are for determining the angle between vectors. Using the vectors I would compute the angle between the vector that goes from (0, 0) to the point I have, and that doesn't give me the angles inside the triangle.

OK, here's some code in Python after the method on the Wikipedia page and after subtracting the values:

import numpy as np
points = np.array([[343.8998, 168.1526], [351.2377, 173.7503], [353.531, 182.72]])

A = points[2] - points[0]
B = points[1] - points[0]
C = points[2] - points[1]

for e1, e2 in ((A, B), (A, C), (B, C)):
    num = np.dot(e1, e2)
    denom = np.linalg.norm(e1) * np.linalg.norm(e2)
    print np.arccos(num/denom) * 180

That gives me 60.2912487814, 60.0951900475 and 120.386438829, so what am I doing wrong?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
luct
  • 423
  • 4
  • 4
  • How is your triangle represented? 3 pairs of `(x,y)` coordinates? – Matt Ball Feb 25 '11 at 20:43
  • @matt yes, just like that. @peter i just want an algorithm, so you can use java/c++ synthax or python. i understand both – luct Feb 25 '11 at 20:44
  • 7
    Is this actually a programming question? Post some source code, otherwise this belongs on http://math.stackexchange.com/ – Mike Atlas Feb 25 '11 at 20:44
  • 3
    The vector from one point `X` to another point `Y` is `Y-X` – mokus Feb 25 '11 at 20:44
  • What do you mean by `angles inside the triangle` ? – Mahesh Feb 25 '11 at 20:46
  • @mokus i tried like that but didn't get the expected results. although the points i'm using are all positive and so they only fall on the first quadrant, so maybe i made a mistake. hmm. – luct Feb 25 '11 at 20:47
  • 1
    `B-A` & `C-A` gives two vectors. And dot product between them gives the angles. – Mahesh Feb 25 '11 at 20:48

6 Answers6

39

There are two errors here.

  • You missed a factor of π when translating from radians to degrees (it's × 180 / π)

  • You have to be careful about the signs of vectors, since they are directed line segments.

If I make these modifications I get a result that makes sense:

import numpy as np
points = np.array([[343.8998, 168.1526], [351.2377, 173.7503], [353.531, 182.72]])

A = points[2] - points[0]
B = points[1] - points[0]
C = points[2] - points[1]

angles = []
for e1, e2 in ((A, B), (A, C), (B, -C)):
    num = np.dot(e1, e2)
    denom = np.linalg.norm(e1) * np.linalg.norm(e2)
    angles.append(np.arccos(num/denom) * 180 / np.pi)
print angles
print sum(angles)

which prints out

[19.191300537488704, 19.12889310421054, 141.67980635830079]
180.0

I'd probably make things more symmetrical and use A, B, C vectors that are cyclic and sum to zero:

import numpy as np
points = np.array([[343.8998, 168.1526], [351.2377, 173.7503], [353.531, 182.72]])

A = points[1] - points[0]
B = points[2] - points[1]
C = points[0] - points[2]

angles = []
for e1, e2 in ((A, -B), (B, -C), (C, -A)):
    num = np.dot(e1, e2)
    denom = np.linalg.norm(e1) * np.linalg.norm(e2)
    angles.append(np.arccos(num/denom) * 180 / np.pi)
print angles
print sum(angles)

which prints out

[141.67980635830079, 19.12889310421054, 19.191300537488704]
180.0

The minus signs in the dot product come because we're trying to get the inside angles.

I'm sorry we drove you away in your time of need, by closing the question.

Jason S
  • 184,598
  • 164
  • 608
  • 970
  • Your answer is featured on http://www.embeddedrelated.com/showarticle/741.php :P Yes I know you wrote it.. Just sayin :) – Sameer Alibhai Feb 17 '15 at 18:06
  • 9
    Well, at the time I wrote the article, this question was closed, so I couldn't post an answer here. I voted to reopen, and other people agreed with me, so then I posted it here as well. – Jason S Feb 17 '15 at 19:21
4

I would use the law of cosines, since you can easily calculate the length of each side of the triangle and then solve for each angles individually.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JoshAdel
  • 66,734
  • 27
  • 141
  • 140
1

Only need to calculate two angles, the third can calculated from the first two.

First angle, take two vectors B-A, C-A, for the second C-B, A-B

points = np.array([[343.8998, 168.1526], [351.2377, 173.7503], [353.531, 182.72]])
A,B,C = points[0], points[1], points[2]

e1 = B-A; e2 = C-A
denom = np.linalg.norm(e1) * np.linalg.norm(e2)
d1 = np.rad2deg(np.arccos(np.dot(e1, e2)/denom))

e1 = C-B; e2 = A-B
denom = np.linalg.norm(e1) * np.linalg.norm(e2)
d2 = np.rad2deg(np.arccos(np.dot(e1, e2)/denom))

d3 = 180-d1-d2

print (d1,d2,d3)

The output is

19.191300537488704 141.6798063583008 19.128893104210505
BBSysDyn
  • 4,389
  • 8
  • 48
  • 63
0

Alternatively, if you only know the length of the sides of the triangle, you can use the Law of cosines.

biziclop
  • 48,926
  • 12
  • 77
  • 104
0

Suppose that you want the angle at A. Then you need to find the angle between the vector from A to B and the vector from A to C. The vector from A to B is just B-A. (Subtract the coordinates.)

btilly
  • 43,296
  • 3
  • 59
  • 88
0

Create three vectors, one from v2 to v1 (v2-v1), one from v3 to v1 (v3-v1), and one from v3 to v2 (v3-v2). Once you have these three vectors, you can use the algorithms you already found along with the fact that all the angles will add to 180 degrees.

Davido
  • 2,913
  • 24
  • 38