10

我正在做一些事情,我在坐标系统 A 中有一架飞机,上面已经有一组点。我在空间 N 中也有一个法线向量。如何旋转坐标 sys A 上的点,以使底层平面具有与 N 相同的法线方向?

想知道是否有人对如何做到这一点有一个好主意。谢谢

4

3 回答 3

24

如果您有或可以轻松计算您的点当前所在平面的法线向量,我认为最简单的方法是围绕两个平面的公共轴旋转。以下是我的做法:

  1. M成为您当前平面N的法线向量,并成为您要旋转到的平面的法线向量。如果M == N您现在可以停止并保持原点不变。
  2. 计算旋转角度为

    costheta = dot(M,N)/(norm(M)*norm(N))
    
  3. 计算旋转轴为

    axis = unitcross(M, N)
    

    其中unitcross是一个执行叉积并将其归一化为单位向量的函数,即unitcross(a, b) = cross(a, b) / norm(cross(a, b))。正如user1318499在评论中指出的那样,此步骤可能会导致错误 if M == N,除非您的实现unitcross返回(0,0,0)when a == b

  4. 从轴和角度计算旋转矩阵为

    c = costheta
    s = sqrt(1-c*c)
    C = 1-c
    rmat = matrix([ x*x*C+c    x*y*C-z*s  x*z*C+y*s ],
                  [ y*x*C+z*s  y*y*C+c    y*z*C-x*s ]
                  [ z*x*C-y*s  z*y*C+x*s  z*z*C+c   ])
    

    其中x,yz是 的组成部分axis。这个公式在 Wikipedia 上有描述。

  5. 对于每个点,计算其在新平面上的对应点为

    newpoint = dot(rmat, point)
    

    其中函数dot执行矩阵乘法。

当然,这不是唯一的。正如彼得克的回答中提到的那样,您可以进行无数次可能的旋转,这会将平面法线M转换为平面法线N。这对应于这样一个事实,在您执行上述步骤后,您可以围绕 旋转平面N,您的点将在不同的位置,同时保持在同一个平面上。(换句话说,您可以进行的满足您的条件的每个旋转都对应于执行上述过程,然后围绕 进行另一次旋转N。)但是,如果您不关心您的点在平面上的哪个位置,我认为围绕公共轴是将点放入您想要的平面的最简单方法。


如果您没有M,但您确实有起始平面中的点相对于该平面原点的坐标,则可以从两个点的位置计算起始法线向量x1x2如下所示

M = cross(x1, x2)

(您也可以unitcross在此处使用,但没有任何区别)。如果您有相对于不在平面内的原点的点坐标,您仍然可以这样做,但您需要三个点的位置:

M = cross(x3-x1, x3-x2)
于 2012-02-24T00:56:54.160 回答
1

单个向量(您的法线 - N)是不够的。对于其他两个维度,您将需要另外两个向量。(想象一下,您的 3D 空间仍然可以围绕法线向量旋转/旋转,并且您需要另外 2 个向量来确定它)。一旦您在飞机上拥有普通的和另一个,第三个应该很容易找到(取决于您的系统是左手还是右手)。

确保所有三个都归一化(长度为 1)并将它们放入矩阵中;使用该矩阵转换 3D 空间中的任何点(使用矩阵乘法)。这应该给你新的坐标。

于 2012-02-24T00:39:55.597 回答
0

我正在考虑制作一个单位向量 [0,0,1] 并使用沿两个平面的点积来找到差异角度,并将所有点移动这些角度。这是假设您希望 z 轴与法线向量对齐,否则只需将 [1,0,0] 或 [0,1,0] 分别用于 x 和 y。

于 2012-02-24T00:32:24.110 回答