Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

math - Calculating angle between two vectors in python

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

enter image description here

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...