Calculating angles between line segments (Python) with math.atan2

六眼飞鱼酱① 提交于 2019-12-03 14:12:15

The easiest and most logically way to get at this problem is using the dot-product.

Try this code (I've commented practically everything):

import math
def dot(vA, vB):
    return vA[0]*vB[0]+vA[1]*vB[1]
def ang(lineA, lineB):
    # Get nicer vector form
    vA = [(lineA[0][0]-lineA[1][0]), (lineA[0][1]-lineA[1][1])]
    vB = [(lineB[0][0]-lineB[1][0]), (lineB[0][1]-lineB[1][1])]
    # Get dot prod
    dot_prod = dot(vA, vB)
    # Get magnitudes
    magA = dot(vA, vA)**0.5
    magB = dot(vB, vB)**0.5
    # Get cosine value
    cos_ = dot_prod/magA/magB
    # Get angle in radians and then convert to degrees
    angle = math.acos(dot_prod/magB/magA)
    # Basically doing angle <- angle mod 360
    ang_deg = math.degrees(angle)%360

    if ang_deg-180>=0:
        # As in if statement
        return 360 - ang_deg
    else: 

        return ang_deg

Now try your variations of lineA and lineB and all should give the same answer.

Too much work. Take the absolute value of the arccosine of the dot product of the two vectors divided by each of the lengths of the lines.

An alternative solution using the formula:

where 'm1' is the slope of line 1 and 'm2' the slope of line 2. If line 1 is defined by the points P1 = [x1, y1] and P2 = [x2, y2], then slope 'm' is:

By using the formulas above you can find the angle in degrees between two lines as follows:

def slope(x1, y1, x2, y2): # Line slope given two points:
    return (y2-y1)/(x2-x1)

def angle(s1, s2): 
    return math.degrees(math.atan((s2-s1)/(1+(s2*s1))))

lineA = ((0.6, 3.6), (1.6, 3))
lineB = ((1.6, 3), (2, 3.6))

slope1 = slope(lineA[0][0], lineA[0][1], lineA[1][0], lineA[1][1])
slope2 = slope(lineB[0][0], lineB[0][1], lineB[1][0], lineB[1][1])

ang = angle(slope1, slope2)
print('Angle in degrees = ', ang)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!