Eri*_*ric 16 python math angle
我一直没有使用数学,这应该是一个简单的问题需要解决.
假设我有两个点A:(1,0)和B:(1,-1).
我想使用程序(Python或任何编程语言)来计算A,原点(0,0)和B之间的顺时针角度.它将是这样的:
angle_clockwise(point1, point2)
Run Code Online (Sandbox Code Playgroud)
请注意,参数的顺序很重要.由于角度计算将是顺时针的:
换句话说,算法是这样的:
有没有办法编码这个问题?
ali*_*i_m 22
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))
Run Code Online (Sandbox Code Playgroud)
例如:
A = (1, 0)
B = (1, -1)
print(angle_between(A, B))
# 45.
print(angle_between(B, A))
# 315.
Run Code Online (Sandbox Code Playgroud)
如果你不想使用numpy,你可以使用math.atan2代替np.arctan2,并使用math.degrees(或只是乘以180 / math.pi)以便从弧度转换为度数.的numpy的版本的一个好处是,你还可以传递两个(2, ...)数组的p1并p2以计算的方式矢量多对点之间的角度.
Chr*_*rre 10
使用内积和两个向量的行列式.如果你想了解它的工作原理,这就是你应该理解的.您需要了解/阅读有关矢量数学的知识.
请参阅:https://en.wikipedia.org/wiki/Dot_product和https://en.wikipedia.org/wiki/Determinant
from math import acos
from math import sqrt
from math import pi
def length(v):
return sqrt(v[0]**2+v[1]**2)
def dot_product(v,w):
return v[0]*w[0]+v[1]*w[1]
def determinant(v,w):
return v[0]*w[1]-v[1]*w[0]
def inner_angle(v,w):
cosx=dot_product(v,w)/(length(v)*length(w))
rad=acos(cosx) # in radians
return rad*180/pi # returns degrees
def angle_clockwise(A, B):
inner=inner_angle(A,B)
det = determinant(A,B)
if det<0: #this is a property of the det. If the det < 0 then B is clockwise of A
return inner
else: # if the det > 0 then A is immediately clockwise of B
return 360-inner
Run Code Online (Sandbox Code Playgroud)
在行列式计算中,您将两个向量连接起来形成一个2 x 2矩阵,为此计算行列式.
经过验证的 0\xc2\xb0 到 360\xc2\xb0 解决方案
\n这是一个旧线程,但对我来说其他解决方案效果不佳,所以我实现了自己的版本。
\n我的函数将为屏幕上的两个点返回 0 到 360(不包括 360)之间的数字(即“y”从顶部开始并向底部增加),其中结果如指南针所示,0\xc2\xb0 位于顶部,顺时针增加:
\ndef angle_between_points(p1, p2):\n d1 = p2[0] - p1[0]\n d2 = p2[1] - p1[1]\n if d1 == 0:\n if d2 == 0: # same points?\n deg = 0\n else:\n deg = 0 if p1[1] > p2[1] else 180\n elif d2 == 0:\n deg = 90 if p1[0] < p2[0] else 270\n else:\n deg = math.atan(d2 / d1) / pi * 180\n lowering = p1[1] < p2[1]\n if (lowering and deg < 0) or (not lowering and deg > 0):\n deg += 270\n else:\n deg += 90\n return deg\nRun Code Online (Sandbox Code Playgroud)\n
这是一个不需要的解决方案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
Run Code Online (Sandbox Code Playgroud)