ik-heu

在进行三维图形处理时,经常会遇到图形的旋转问题。在船舶领域,船体的倾斜、摇摆计算也会涉及到坐标旋转的处理。本文总结了坐标点饶坐标轴以及绕任意轴的处理方法。

1 绕坐标轴的旋转

先考虑简单的情形,以绕$x$轴的旋转为例,$P_{yz}$为点$P$在$yz$平面上的投影,$\phi_{xo}$为$OP_{yz}$和$y$轴的夹角,${P_{yz}}'$为$P_{yz}$按右手方向绕$x$轴旋转$\phi_x$后的点。只需进行简单的三角变换即可获得旋转后的新坐标$\left( {{x_x},{y_x},{z_x}} \right)$:

\[\left\{ \begin{array}{l}
{x_x} = x\\
{y_x} = {r_{yz}}\cos \left( {{\phi _{xo}} + {\phi _x}} \right)\\
{\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} = {r_{yz}}\cos {\phi _{xo}}\cos {\phi _x} - {r_{yz}}\sin {\phi _{xo}}\sin {\phi _x}\\
{\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} = y\cos {\phi _x} - z\sin {\phi _x}\\
{z_x} = {r_{yz}}\sin \left( {{\phi _{xo}} + {\phi _z}} \right)\\
{\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} = {r_{yz}}\sin {\phi _{xo}}\cos {\phi _z} + {r_{yz}}\cos {\phi _{xo}}\sin {\phi _z}\\
{\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} {\kern 1pt} = z\cos {\phi _z} + y\sin {\phi _z}
\end{array} \right.\] 

可以将上式写成矩阵形式:

\[\left( \begin{array}{l}
{x_x}\\
{y_x}\\
{z_x}
\end{array} \right) = \left( {\begin{array}{*{20}{c}}
1&0&0\\
0&{\cos {\phi _x}}&{ - \sin {\phi _x}}\\
0&{\sin {\phi _x}}&{\cos {\phi _x}}
\end{array}} \right)\left( \begin{array}{l}
x\\
y\\
z
\end{array} \right)\]

同样可以推导出坐标点绕$y$轴、$z$轴旋转计算的系数矩阵。$(x,y,z)$依次绕三条坐标轴$x$、$y$、$z$分别旋转 $\phi_x$、$\phi_y$、$\phi_z$后的坐标$(x',y',z')$可表示为:

\[\left( \begin{array}{l}
x'\\
y'\\
z'
\end{array} \right) = \left( {\begin{array}{*{20}{c}}
1&0&0\\
0&{\cos {\phi _x}}&{ - \sin {\phi _x}}\\
0&{\sin {\phi _x}}&{\cos {\phi _x}}
\end{array}} \right)\left( {\begin{array}{*{20}{c}}
{\cos {\phi _y}}&0&{\sin {\phi _y}}\\
0&1&0\\
{ - \sin {\phi _y}}&0&{\cos {\phi _y}}
\end{array}} \right)\left( {\begin{array}{*{20}{c}}
{\cos {\phi _z}}&{ - \sin {\phi _z}}&0\\
{\sin {\phi _z}}&{\cos {\phi _z}}&0\\
0&0&1
\end{array}} \right)\left( \begin{array}{l}
x\\
y\\
z
\end{array} \right)\]

一方面,对于一般的矩阵运算,$AB = BA$ 是不成立的;另一方面,角度(或弧度)这个物理量不是矢量,不满足平行四边形定律。因此在使用上面这个式子计算坐标时,需要注意饶轴旋转的顺序是不可以颠倒的。

2 绕任意轴的旋转

有时需要对坐标进行任意方向的处理,那么绕任意轴旋转的坐标该怎么计算呢?实际上有现成的计算公式,这个公式的推导过程相当复杂,可以参考绕任意轴旋转。这里直接给出计算方法。点$P(x,y,z)$以右手方向,绕过原点的单位矢量$e = {e_x}{\bf{i}} + {e_y}{\bf{j}} + {e_z}{\bf{k}}$旋转$\phi$后的坐标$P'(x',y',z')$可表示为:

\[\left( \begin{array}{l}
x'\\
y'\\
z'
\end{array} \right) = \left( {\begin{array}{*{20}{c}}
{\left( {1 - c} \right){e_x}^2 + c}&{\left( {1 - c} \right){e_x}{e_y} - {e_z}s}&{\left( {1 - c} \right){e_x}{e_z} + {e_y}s}\\
{\left( {1 - c} \right){e_y}{e_x} + {e_z}s}&{\left( {1 - c} \right){e_y}^2 + c}&{\left( {1 - c} \right){e_y}{e_z} - {e_x}s}\\
{\left( {1 - c} \right){e_x}{e_z} - {e_y}s}&{\left( {1 - c} \right){e_y}{e_z} + {e_x}s}&{\left( {1 - c} \right){e_z}^2 + c}
\end{array}} \right)\left( \begin{array}{l}
x\\
y\\
z
\end{array} \right)\]

绕任意轴旋转坐标计算的Python代码: 

# -*- coding: utf-8 -*-
import numpy as np 

def rotation_3d(position, axis, angle):
    '''
    position:原坐标(x, y, z)
        axis:旋转的坐标轴(ex, ey, ez)
       angle: 旋转弧度
    '''
    ex, ey, ez = axis
    ex, ey, ez = [x / np.sqrt(ex ** 2 + ey ** 2 + ez ** 2) #归一化
                    for x in axis]
    s, c = np.sin(angle), np.cos(angle), 
    matrix1 = np.array([[ex ** 2, ex * ey, ex * ez], 
                        [ey * ex, ey ** 2, ey * ez],
                        [ex * ez, ey * ez, ez ** 2]]);
    matrix2 = np.array([[c, -ez * s, ey * s], 
                        [ez * s, c, -ex * s],
                        [-ey * s, ex * s, c]]);
    matrix = (1 - c) * matrix1 + matrix2
    return matrix.dot(np.array(position).reshape(3,1))\
               .reshape(1,3).tolist()[0]

 

更多坐标旋转的资料可参考:Rotation matrix

分类:

技术点:

python

相关文章: