我需要確定Python中兩個n維向量之間的角度。例如,輸入可以是兩個列表,如下所示:[1,2,3,4]
和[6,7,8,9]
。Python中兩個n維向量之間的角度
回答
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)))
注意:當向量具有相同或相反的方向,這將失敗。正確的實現是在這裏:https://stackoverflow.com/a/13849249/71522
使用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
最後一行可能會導致一個錯誤,因爲我已經找到由於舍入錯誤而退出。因此,如果你點(u,u)/ norm(u)** 2,結果爲1.0000000002,然後arccos失敗(對於反平行矢量也是「有效的」) – BandGap 2012-01-27 11:10:45
我用u = [1,1,1 ]。 u = [1,1,1,1]可以正常工作,但每個維度添加的返回值稍大於或小於1 ... – BandGap 2012-01-27 11:20:06
注意:**這將失敗**(yield'nan')當兩個方向向量是相同的或相反的。查看我的答案以獲得更正確的版本。 – 2012-12-12 21:52:43
注意:如果兩個向量要麼向同一方向(例如,(1, 0, 0)
,(1, 0, 0)
)或相反方向(例如,(-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))
使用'np.isnan'而不是數學庫中的那個會更好嗎?理論上它們應該是相同的,但我在實踐中不太確定。無論哪種方式,我會想象它會更安全。 – Hooked 2013-07-15 15:52:59
唯一的區別是,如果輸入是一個數組,那麼np.isnan會做一些明智的事情,這在這裏永遠不會出現。然而,使用'np.isnan'肯定會更清晰(不知道爲什麼我使用'math.isnan' ...),所以我會切換它。 – 2013-07-15 16:03:02
您也可以使用'angle = np.arccos(np.clip(np.dot(v1_u,v2_u), - 1,1))'並跳過if-else業務。 – letmaik 2014-01-13 10:59:37
使用numpy的和照顧的帶隙的舍入誤差:
from numpy.linalg import norm
from numpy import dot
import math
def angle_between(a,b):
arccosInput = dot(a,b)/norm(a)/norm(b)
arccosInput = 1.0 if arccosInput > 1.0 else arccosInput
arccosInput = -1.0 if arccosInput < -1.0 else arccosInput
return math.acos(arccosInput)
注意,此功能將如果一個拋出異常矢量的幅度爲零(除以0)。
另一種可能是隻使用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)
這裏是輸出:
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
- 1. 計算兩個三維向量之間的角度爲每個維度
- 2. 兩個向量3D之間的角度? python
- 3. 兩個向量之間的相關性與向量之間的角度
- 4. Matlab中兩個向量之間的角度
- 5. 兩個2d向量之間的角度,兩種方法之間的差異?
- 6. 獲取一個圓上的兩個向量之間的角度
- 7. 在兩個向量vpython之間創建一個角度?
- 8. 使用點積來計算兩個向量之間的角度
- 9. 如何計算兩個向量之間的角度?
- 10. 找到兩個向量之間的角度
- 11. 如何找到兩個向量之間的角度?
- 12. Java Vector3計算兩個向量之間的角度
- 13. 三維矢量角度 - 得到兩個
- 14. 計算角度包括兩個矢量之間的反射角度
- 15. 與結果範圍0兩個3D向量之間的角度 - 360
- 16. Matlab atan2兩個3D矢量之間的角度
- 17. OpenCV - 如何檢測和測量兩個幀之間的角度?
- 18. 通過在Python中使用簡單的numpy或數學計算兩個向量之間的角度?
- 19. 2個向量之間的度數?
- 20. 二維矢量之間的帶符號角度
- 21. 圖的兩條邊之間的角度
- 22. Python,兩個向量之間的DotProduct問題
- 23. 如何測量兩個python代碼塊之間的相似度?
- 24. 尋找兩點之間的角度
- 25. SSAS中兩個維度之間的關係
- 26. 如何測量matlab中兩個二維複雜場之間的相似度?
- 27. 如何找出兩個矢量之間的角度是外部還是內部? (在三維空間)
- 28. 分裂兩個度數值之間的角度
- 29. 計算兩個緯度/經度點之間的夾角
- 30. Java:以度爲單位計算兩個點之間的角度
另外,如果你只需要cos,sin,tan的角度,而不是角度本身,那麼你可以跳過math.acos得到餘弦,並使用交叉乘積得到正弦。 – mbeckish 2010-05-13 14:17:28
這正是我正在尋找的,謝謝! – Peter 2010-05-13 14:36:59
鑑於'math.sqrt(x)'等同於'x ** 0.5','math.pow(x,y)'等價於'x ** y',我很驚訝這些倖存下來的冗餘軸在Python 2.x-> 3.0轉換期間運行。在實踐中,我通常將這些數字事物作爲更大計算密集型過程的一部分,並且解釋器對'**'的支持直接轉到字節碼BINARY_POWER,而不是查找'數學',訪問到其屬性'sqrt',然後緩慢的字節碼CALL_FUNCTION,可以在無編碼或可讀性成本的情況下在速度上做出可測量的改進。 – PaulMcG 2010-05-14 07:11:08