计算两点之间的角度(顺时针)

时间:2015-07-30 23:01:59

标签: python math angle

我长时间没有使用数学,这应该是一个很难解决的问题。

假设我有两个点A:(1,0)和B:(1,-1)。

我想用一个程序(Python或其他编程语言)来计算A,原点(0,0)和B之间的顺时针角度。它将是这样的:

angle_clockwise(point1, point2)

请注意,参数的顺序很重要。由于角度计算将是顺时针:

  • 如果我调用angle_clockwise(A,B),则返回45。
  • 如果我调用angle_clockwise(B,A),则返回315。

换句话说,算法是这样的:

  1. 在第一个点参数与(0,0)之间画一条线(第1行)。
  2. 在第二个点参数与(0,0)之间画一条线(第2行)。
  3. 顺时针旋转第1行(0,0),直到它与第2行重叠。
  4. 行进的角距离线1将是返回的角度。
  5. 有没有办法对此问题进行编码?

8 个答案:

答案 0 :(得分:19)

Numpy的arctan2(y, x)将计算原点和点(x, y)之间的逆时针角度(-π和π之间的弧度值)。

您可以为点AB执行此操作,然后从第一个角度减去第二个角度,以获得带符号的顺时针角度差。这个差异在-2π和2π之间,所以为了得到0到2π之间的正角,你可以取模2/2。最后,您可以使用np.rad2deg将弧度转换为度数。

import numpy as np

def angle_between(p1, p2):
    ang1 = np.arctan2(*p1[::-1])
    ang2 = np.arctan2(*p2[::-1])
    return np.rad2deg((ang1 - ang2) % (2 * np.pi))

例如:

A = (1, 0)
B = (1, -1)

print(angle_between(A, B))
# 45.

print(angle_between(B, A))
# 315.

如果您不想使用numpy,可以使用math.atan2代替np.arctan2,并使用math.degrees(或只是乘以180 / math.pi)从弧度转换为度数。 numpy版本的一个优点是,您还可以为(2, ...)p1传递两个p2数组,以便以矢量化方式计算多对点之间的角度。

答案 1 :(得分:9)

使用内积和两个向量的行列式。如果你想了解它的工作原理,这就是你应该理解的。您需要了解/阅读有关矢量数学的知识。

请参阅:https://en.wikipedia.org/wiki/Dot_producthttps://en.wikipedia.org/wiki/Determinant

function LCM_N(n) {
    var x = 1;
    while (n > 1) {
        x = LCM(n, x);
        n--;
    }
    return x;
}

在行列式计算中,您将两个向量连接起来形成一个2 x 2矩阵,为此计算行列式。

答案 2 :(得分:5)

这是一个不需要cmath的解决方案。

import math

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

v1 = Vector(0, 1)
v2 = Vector(0, -1)

v1_theta = math.atan2(v1.y, v1.x)
v2_theta = math.atan2(v2.y, v2.x)

r = (v2_theta - v1_theta) * (180.0 / math.pi)

if r < 0:
    r += 360.0

print r

答案 3 :(得分:1)

查看cmath python库。

>>> import cmath
>>> a_phase = cmath.phase(complex(1,0))
>>> b_phase = cmath.phase(complex(1,-1))
>>> (a_phase - b_phase) * 180 / cmath.pi
45.0
>>> (b_phase - a_phase) * 180 / cmath.pi
-45.0

如果您想要所有正角度,您可以检查数字是否小于0并为其添加360.

答案 4 :(得分:1)

Chris St Pierre:在使用你的功能时:

A = (x=1, y=0)
B = (x=0, y=1)

这应该是从90A的{​​{1}}度角。您的函数将返回B

如何处理det的标志或者我遗漏了什么?

答案 5 :(得分:0)

计算顺时针角度的公式,用于测量:

f(E,N)=pi()-pi()/2*(1+sign(N))* (1-sign(E^2))-pi()/4*(2+sign(N))*sign(E)

     -sign(N*E)*atan((abs(N)-abs(E))/(abs(N)+abs(E)))

公式给出的角度为0到2pi,从北方开始,

适用于任何值 N E 。 ( N = N2-N1和E = E2-E1

对于 N = E = 0 ,结果是不确定的。

答案 6 :(得分:0)

经过验证的0°至360°的解决方案

这是一个旧线程,但是对我而言,其他解决方案效果不佳,因此我实现了自己的版本。

我的函数将为屏幕上的两个点返回一个介于0到360之间的数字(不包括360)(即,“ y”从顶部开始并向底部增加),其结果类似于指南针,0度表示顶部,顺时针方向增加:

<Code>dim Counter as integer=0
Public function getCounter() as Integer
Counter=Counter+1
return Counter
end function</Code>

答案 7 :(得分:0)

以弧度为单位,顺时针,从 0 到 PI * 2

static angle(center:Coord, p1:Coord, p2:Coord) {
    var a1 = Math.atan2(p1.y - center.y, p1.x - center.x);
    var a2 = Math.atan2(p2.y - center.y, p2.x -center.x);
    a1 = a1 > 0 ? a1 : Math.PI * 2 + a1;//make angle from 0 to PI * 2
    a2 = a2 > 0 ? a2 : Math.PI * 2 + a2;
    if(a1 > a2) {
        return a1 - a2;
    } else {
        return Math.PI * 2 - (a2 - a1)
    }
}