2012-06-21 33 views
5

什麼是公式得到一個三維向量B躺在垂直於向量A的平面上?什麼是使矢量垂直於另一個矢量的公式?

也就是說,給定一個向量A,給出一個垂直於A的向量的公式f(角度,模量)

+0

有兩件事:第一,我們是否在二維操作?三? 'N'?其次,你的頭銜說「垂直」,但問題身體說「通過一個角度旋轉」 - 這個角度會不會超過九十度? – AakashM

+1

在3維中,存在與給定矢量垂直的無限多個不同矢量(2維矢量空間)。公式不會生成單個向量。 – 2012-06-21 11:45:32

回答

8

如果兩個向量垂直那麼它們的點積爲零。因此:v1(x1, y1, z1), v2(x2, y2, z2)

=> x1 * x2 + y1 * y2 + z1 * z2 = 0 

你知道嗎(x1, y1, z1)。把任意x2y2,您將收到相應的z2

z1 * z2 = -x1 * x2 - y1 * y2 
=> z2 = (-x1 * x2 - y1 * y2)/z1 

要知道,如果z10。然後你在飛機上。

+0

只有一個向量。 – MaiaVictor

+4

是的。你有一個給定'v1(x1,y1,z1)'的向量。 –

+1

正如你所提到的,如果'z1'爲0,則失敗,但在這種情況下,問題在數學上仍然是完全有效的。例如,查找垂直於[1,0,0]的矢量。 'z1'爲0,但[0,1,0]絕對是一個垂直於[1,0,0]的向量。看到我的答案替代方法。 – sircolinton

6

用另一個與A不共線的載體C來計算cross productAxC

垂直於A的平面上有很多可能的方向。如果你真的不關心,哪一個選擇,只需創建一個任意矢量CA共線:

if (A2 != 0 || A3 != 0) 
    C = (1, 0, 0); 
else 
    C = (0, 1, 0); 
B = A x C; 
+0

只有一個向量,我想要一個公式給出一個與它垂直的矢量,它的角度和長度的函數。 – MaiaVictor

+1

Dokkat,你在描述中保留兩個向量的原因是因爲給定第一個向量V1,存在許多垂直於V1的向量V2。在二維空間中,至少有兩個長度爲1的矢量。在三維空間中,有垂直於V1的無限多個矢量!你想要找到的是一個任意的V2(perp到V1),或者你想檢測(V1,V2)是否垂直。 –

+1

@Dokkat - 看我的編輯。 – Henrik

1

一種方法是找到從正z軸(或任何其他軸)到給定向量的旋轉變換。然後使用這個變換來變換<modulus * cos(angle), modulus * sin(angle), 0>

def getPerpendicular(v1,modulus,angle): 
    v2 = vector(0,0,1) 
    v1_len = v2.length() 

    axis = v1.cross_product(v2) 
    sinAngle = axis.length()/v1_len  # |u x v| = |u| * |v| * sin(angle) 
    cosAngle = v1.dot_product(v2)/v1_len # u . v = |u| * |v| * cos(angle) 
    axis = axis.normalize() 
    # atan2(sin(a), cos(a)) = a, -pi < a < pi 
    angle = math.atan2(sinAngle, cosAngle) 

    rotationMatrix = fromAxisAngle(axis, angle) 

    # perpendicular to v2 
    v3 = vector(modulus*cos(angle),modulus*sin(angle),0) 

    return rotationMatrix.multiply(v3); 

要計算旋轉矩陣,看到這篇文章:WP: Rotation matrix from axis and angle

另一種方法是使用quaternion rotation。多繞一圈,但是跟蹤的數量要少一些。

4
function (a,b,c) 
{ 
    return (-b,a,0) 
} 

但這答案不是當a,b是接近0

爲了避免這種情況下,使用數值穩定:

function (a,b,c) 
{ 
    return c<a ? (b,-a,0) : (0,-c,b) 
} 

以上回答是數值穩定的,因爲在case c < a then max(a,b) = max(a,b,c),然後vector(b,-a,0).length() > max(a,b) = max(a,b,c),並且由於max(a,b,c)不應該接近零,因此矢量也是如此。 c > a情況類似。

+0

僅供參考,我循環使用了10,000個隨機單位向量,並確保所有向量的'點(vec,above_func(vec))== 0'(我懶得試圖通過分析驗證穩定性,所以這個是我下一個最好的選擇)。它工作完美。 – Steve

+2

如果向量是例如(a = 0,b = 0,c = -1),則c

+1

@GiovanniFunchal事實上,「max(a,b,c)不應該接近於零」的陳述即使對於「好」向量也可能是假的,就像你提到的那樣。解釋應該使用L-infinity範數而不是max來校正,並且c Fabio

1

我認爲,這應該產生的垂直於給定的矢量vec同時保持數值穩定不管vec角度的任意向量(假設的vec大小不接近零)。假設Vec3D是任意數值類型的三維向量。

Vec3D arbitrary_orthogonal(Vec3D vec) 
{ 
    bool b0 = (vec[0] < vec[1]) && (vec[0] < vec[2]); 
    bool b1 = (vec[1] <= vec[0]) && (vec[1] < vec[2]); 
    bool b2 = (vec[2] <= vec[0]) && (vec[2] <= vec[1]); 

    return cross(vec, Vec3D(int(b0), int(b1), int(b2))); 
} 
0

q4w56的幾乎是一個強大的解決方案。問題:1)不考慮縮放。2)不應該比較兩個變量之間的大小。

scale = |x| + |y| + |z| 

if scale == 0: 
    return (0,0,0) 

x = x/scale 
y = y/scale 
z = z/scale 

if |x| > |y|: 
    return (z, 0,-x) 
else: 
    return (0, z,-y) 

當處理非常大或非常小的數字時,縮放非常重要。另外一般情況下,你最好在0到1之間的值上進行浮點運算。