我长时间没有使用数学,这应该是一个很难解决的问题。
假设我有两个点A:(1,0)和B:(1,-1)。
我想用一个程序(Python或其他编程语言)来计算A,原点(0,0)和B之间的顺时针角度。它将是这样的:
angle_clockwise(point1, point2)
请注意,参数的顺序很重要。由于角度计算将是顺时针:
换句话说,算法是这样的:
有没有办法对此问题进行编码?
答案 0 :(得分:19)
Numpy的arctan2(y, x)
将计算原点和点(x, y)
之间的逆时针角度(-π和π之间的弧度值)。
您可以为点A
和B
执行此操作,然后从第一个角度减去第二个角度,以获得带符号的顺时针角度差。这个差异在-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_product和https://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)
这应该是从90
到A
的{{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)
}
}