Dav*_*d Z 17
如果你有或者可以很容易地计算出你的点当前所在平面的法向量,我认为最简单的方法是围绕两个平面共有的轴旋转.这是我如何去做的:
M正常您当前平面向量,N是正常要旋转到平面向量.如果M == N您现在可以停止并保持原始点不变.计算旋转角度为
costheta = dot(M,N)/(norm(M)*norm(N))
Run Code Online (Sandbox Code Playgroud)计算旋转轴为
axis = unitcross(M, N)
Run Code Online (Sandbox Code Playgroud)
where unitcross是一个执行交叉乘积并将其规范化为单位向量的函数,即unitcross(a, b) = cross(a, b) / norm(cross(a, b)).正如user1318499在注释中指出的那样,如果这个步骤可能会导致错误M == N,除非你执行unitcross返回的(0,0,0)时候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 ])
Run Code Online (Sandbox Code Playgroud)
在哪里x,y和,z是和的组成部分axis.该公式在维基百科上有所描述.
对于每个点,计算新平面上的对应点为
newpoint = dot(rmat, point)
Run Code Online (Sandbox Code Playgroud)
函数dot执行矩阵乘法.
当然,这不是唯一的; 正如peterk的回答中所提到的,你可以进行无限次的旋转,将平面法线转换为法线M平面N.这相当于这样的事实:在您采取上述步骤后,您可以旋转平面N,并且您的点将在不同的位置,同时保持在同一平面.(换句话说,你可以做出的满足条件的每次旋转都对应于上面描述的程序,然后是另一次旋转N.)但如果你不关心你的点在飞机的哪个地方,我认为这个旋转周围公共轴是将点分配到您想要的平面的最简单方法.
如果你没有M,但你有个在开始你的飞机坐标相对于该平面的原点,您可以计算从两个点的位置开始正常的矢量x1和x2作为
M = cross(x1, x2)
Run Code Online (Sandbox Code Playgroud)
(你也可以unitcross在这里使用,但它没有任何区别).如果你有相对于不在平面内的原点的点坐标,你仍然可以这样做,但你需要三个点的位置:
M = cross(x3-x1, x3-x2)
Run Code Online (Sandbox Code Playgroud)