什么是使矢量垂直于另一个矢量的公式?

时间:2012-06-21 06:28:17

标签: math vector formula algebra

什么是使三维矢量B位于垂直于矢量A?

的平面上的公式

也就是说,给定矢量A,什么是公式f(角度,模数),它给出一个垂直于A的矢量,所述模数和旋转角度θ

6 个答案:

答案 0 :(得分:11)

如果两个矢量是垂直的,则它们的点积为零。

所以: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。那你就在飞机上。

答案 1 :(得分:7)

使用另一个与AxC不共线的向量C计算cross product A

在垂直于A的平面中有许多可能的方向。如果你真的不关心,选择哪一个,只需创建一个与C不共线的任意向量A

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

答案 2 :(得分:5)

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

但是当a,b接近0时,这个答案不是数值稳定的。

为避免这种情况,请使用:

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

以上答案是数值稳定的,因为如果c < a然后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案例类似。

答案 3 :(得分:2)

我认为这应该产生一个垂直于给定向量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)));
}

答案 4 :(得分: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。你可以用更多的东西包围你的头脑,但追踪的数字却少了。

答案 5 :(得分:1)

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之间的值上进行浮点运算。