Pet*_*ter 64 python vector angle
我需要确定Python中两个n维向量之间的角度.例如,输入可以是两个列表,如下所示:[1,2,3,4]和[6,7,8,9].
Dav*_*ver 120
注意:如果两个向量具有相同的方向(ex (1, 0, 0),,(1, 0, 0))或相反的方向(ex (-1, 0, 0),,(1, 0, 0)),则此处的所有其他答案都将失败.
这是一个能够正确处理这些情况的函数:
import numpy as np
def unit_vector(vector):
""" Returns the unit vector of the vector. """
return vector / np.linalg.norm(vector)
def angle_between(v1, v2):
""" Returns the angle in radians between vectors 'v1' and 'v2'::
>>> angle_between((1, 0, 0), (0, 1, 0))
1.5707963267948966
>>> angle_between((1, 0, 0), (1, 0, 0))
0.0
>>> angle_between((1, 0, 0), (-1, 0, 0))
3.141592653589793
"""
v1_u = unit_vector(v1)
v2_u = unit_vector(v2)
return np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))
Run Code Online (Sandbox Code Playgroud)
Ale*_*lli 55
import math
def dotproduct(v1, v2):
return sum((a*b) for a, b in zip(v1, v2))
def length(v):
return math.sqrt(dotproduct(v, v))
def angle(v1, v2):
return math.acos(dotproduct(v1, v2) / (length(v1) * length(v2)))
Run Code Online (Sandbox Code Playgroud)
注意:当向量具有相同或相反的方向时,这将失败.正确的实现在这里:https://stackoverflow.com/a/13849249/71522
Oli*_*ier 37
使用numpy(强烈推荐),您可以:
from numpy import (array, dot, arccos, clip)
from numpy.linalg import norm
u = array([1.,2,3,4])
v = ...
c = dot(u,v)/norm(u)/norm(v) # -> cosine of the angle
angle = arccos(clip(c, -1, 1)) # if you really want the angle
Run Code Online (Sandbox Code Playgroud)
小智 23
另一种可能性是使用它numpy,它给你内角
import numpy as np
p0 = [3.5, 6.7]
p1 = [7.9, 8.4]
p2 = [10.8, 4.8]
'''
compute angle (in degrees) for p0p1p2 corner
Inputs:
p0,p1,p2 - points in the form of [x,y]
'''
v0 = np.array(p0) - np.array(p1)
v1 = np.array(p2) - np.array(p1)
angle = np.math.atan2(np.linalg.det([v0,v1]),np.dot(v0,v1))
print np.degrees(angle)
Run Code Online (Sandbox Code Playgroud)
这是输出:
In [2]: p0, p1, p2 = [3.5, 6.7], [7.9, 8.4], [10.8, 4.8]
In [3]: v0 = np.array(p0) - np.array(p1)
In [4]: v1 = np.array(p2) - np.array(p1)
In [5]: v0
Out[5]: array([-4.4, -1.7])
In [6]: v1
Out[6]: array([ 2.9, -3.6])
In [7]: angle = np.math.atan2(np.linalg.det([v0,v1]),np.dot(v0,v1))
In [8]: angle
Out[8]: 1.8802197318858924
In [9]: np.degrees(angle)
Out[9]: 107.72865519428085
Run Code Online (Sandbox Code Playgroud)
找到两个向量之间的角度的简单方法(适用于 n 维向量),
Python代码:
import numpy as np
vector1 = [1,0,0]
vector2 = [0,1,0]
unit_vector1 = vector1 / np.linalg.norm(vector1)
unit_vector2 = vector2 / np.linalg.norm(vector2)
dot_product = np.dot(unit_vector1, unit_vector2)
angle = np.arccos(dot_product) #angle in radian
Run Code Online (Sandbox Code Playgroud)
如果您正在使用 3D 矢量,您可以使用工具带vg简洁地完成此操作。它是 numpy 顶部的一个浅层。
import numpy as np
import vg
vec1 = np.array([1, 2, 3])
vec2 = np.array([7, 8, 9])
vg.angle(vec1, vec2)
Run Code Online (Sandbox Code Playgroud)
您还可以指定视角以通过投影计算角度:
vg.angle(vec1, vec2, look=vg.basis.z)
Run Code Online (Sandbox Code Playgroud)
或通过投影计算有符号角:
vg.signed_angle(vec1, vec2, look=vg.basis.z)
Run Code Online (Sandbox Code Playgroud)
我在上次创业时创建了这个库,它的动机是这样的用途:在 NumPy 中冗长或不透明的简单想法。
David Wolever 的解决方案很好,但是
如果你想要有符号的角度,你必须确定给定的一对是右手还是左手(有关更多信息,请参阅wiki)。
我的解决方案是:
def unit_vector(vector):
""" Returns the unit vector of the vector"""
return vector / np.linalg.norm(vector)
def angle(vector1, vector2):
""" Returns the angle in radians between given vectors"""
v1_u = unit_vector(vector1)
v2_u = unit_vector(vector2)
minor = np.linalg.det(
np.stack((v1_u[-2:], v2_u[-2:]))
)
if minor == 0:
raise NotImplementedError('Too odd vectors =(')
return np.sign(minor) * np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))
Run Code Online (Sandbox Code Playgroud)
因此它并不完美,NotImplementedError但对于我的情况来说它效果很好。这种行为可以修复(因为任何给定的配对都确定了手感),但它需要我想要并且必须编写的更多代码。
| 归档时间: |
|
| 查看次数: |
113814 次 |
| 最近记录: |