繁体   English   中英

从三个x,y点计算角度的更多pythonic方式返回0-360度,“ up”为0?

[英]more pythonic way to calculate angle from three x,y points return 0-360 degrees with “up” as 0?

我正在使用具有所有正值的笛卡尔系统。 我需要计算两个点(x,y,z)之间的平面挠度。 我主要对相对于“北方”参考矢量顺时针返回0-360值感兴趣,尽管我已经编写了函数(我认为),所以我可以将参考矢量分配给任何方向。 以下代码似乎返回了我想要的内容,但是if语句似乎有点hack。 有没有一种更干净的方法可以完全在计算范围内处理它?

我尝试了arctan2,结果相似。

    import numpy as np

    # define 'origin' point where coords are X,Y,Z
    p1 = [10000,10000,0] 

    # create function to compute angle
    def ang(p1,p2):
        """
        p1 is [x,y,z] 'from'
        p2 is [x,y,z] 'to'
        """
        # set reference point relative to p1
        p0 = [p1[0],p1[1]+1000,0] # 1000 unit offset is arbitrary

        # assign X,Y points to variables as arrays
        a = np.array(p0[0:2])
        b = np.array(p1[0:2]) # the origin
        c = np.array(p2[0:2])

        # create vectors
        ba: ndarray = a - b # subtract the origin
        bc: ndarray = c - b # subtract the origin

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

        # adjust for hemisphere
        if bc[0] < 0:
            return(360 - np.degrees(angle))
        else:
            return(np.degrees(angle))

    test_lst = [[10000, 20000,0],[20000, 20000,0],[20000,10000,0],[20000,0,0],[10000,0,0],[0,0,0],[0,10000,0],[0,20000,0]]

    for i in test_lst:
        a = ang(p1,i)
        print(a)

与if语句(这是我想要的):

expected      |     returned
  0.0         |        0.0
 45.0         |       45.0
 90.0         |       90.0
135.0         |      135.0
180.0         |      180.0
225.0         |      225.0
270.0         |      270.0
315.0         |      315.0

没有if语句:

expected      |     returned
  0.0         |        0.0
 45.0         |       45.0
 90.0         |       90.0
135.0         |      135.0
180.0         |      180.0
225.0         |      135.0
270.0         |       90.0
315.0         |       45.0

这不是关于Python,而是关于数学如何工作。 由于可能的正弦/余弦值的[-1, 1]范围映射到180度宽的间隔,因此arccos (还包括arcsin等)函数返回非唯一值。 arctan2返回-180至180度范围内的角度的arctan2 (作为atan2引入C中)来解决同样的问题。 幸运的是,这是一个简单的方法来转换[-180, 180][0, 360]在Python:

angle = np.arctan2(...)
return np.degrees(angle) % 360.0  # the modulo operator does this job well

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM