我正在做一些事情,我在坐标系统 A 中有一架飞机,上面已经有一组点。我在空间 N 中也有一个法线向量。如何旋转坐标 sys A 上的点,以使底层平面具有与 N 相同的法线方向?
想知道是否有人对如何做到这一点有一个好主意。谢谢
如果您有或可以轻松计算您的点当前所在平面的法线向量,我认为最简单的方法是围绕两个平面的公共轴旋转。以下是我的做法:
M
成为您当前平面N
的法线向量,并成为您要旋转到的平面的法线向量。如果M == N
您现在可以停止并保持原点不变。计算旋转角度为
costheta = dot(M,N)/(norm(M)*norm(N))
计算旋转轴为
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
。
从轴和角度计算旋转矩阵为
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
,y
和z
是 的组成部分axis
。这个公式在 Wikipedia 上有描述。
对于每个点,计算其在新平面上的对应点为
newpoint = dot(rmat, point)
其中函数dot
执行矩阵乘法。
当然,这不是唯一的。正如彼得克的回答中提到的那样,您可以进行无数次可能的旋转,这会将平面法线M
转换为平面法线N
。这对应于这样一个事实,在您执行上述步骤后,您可以围绕 旋转平面N
,您的点将在不同的位置,同时保持在同一个平面上。(换句话说,您可以进行的满足您的条件的每个旋转都对应于执行上述过程,然后围绕 进行另一次旋转N
。)但是,如果您不关心您的点在平面上的哪个位置,我认为围绕公共轴是将点放入您想要的平面的最简单方法。
如果您没有M
,但您确实有起始平面中的点相对于该平面原点的坐标,则可以从两个点的位置计算起始法线向量x1
,x2
如下所示
M = cross(x1, x2)
(您也可以unitcross
在此处使用,但没有任何区别)。如果您有相对于不在平面内的原点的点坐标,您仍然可以这样做,但您需要三个点的位置:
M = cross(x3-x1, x3-x2)
单个向量(您的法线 - N)是不够的。对于其他两个维度,您将需要另外两个向量。(想象一下,您的 3D 空间仍然可以围绕法线向量旋转/旋转,并且您需要另外 2 个向量来确定它)。一旦您在飞机上拥有普通的和另一个,第三个应该很容易找到(取决于您的系统是左手还是右手)。
确保所有三个都归一化(长度为 1)并将它们放入矩阵中;使用该矩阵转换 3D 空间中的任何点(使用矩阵乘法)。这应该给你新的坐标。
我正在考虑制作一个单位向量 [0,0,1] 并使用沿两个平面的点积来找到差异角度,并将所有点移动这些角度。这是假设您希望 z 轴与法线向量对齐,否则只需将 [1,0,0] 或 [0,1,0] 分别用于 x 和 y。