java.lang.Object
org.hipparchus.geometry.euclidean.threed.Rotation
所有已实现的接口:
Serializable

public class Rotation extends Object implements Serializable
该类实现了三维空间中的旋转。

旋转可以用几种不同的数学实体表示(矩阵、轴和角、Cardan或Euler角、四元数)。该类提供了一个更高级的抽象,更加面向用户并隐藏了这些实现细节。好吧,对于好奇的人来说,我们在内部表示中使用四元数。用户可以从任何这些表示构建旋转,并且可以从Rotation实例中检索任何这些表示(请参阅各种构造函数和getter)。此外,旋转还可以从一组向量及其映像隐式构建。

这意味着这个类可以用于将一种表示转换为另一种表示。例如,将旋转矩阵转换为一组Cardan角可以使用以下一行代码完成:

 double[] angles = new Rotation(matrix, 1.0e-10).getAngles(RotationOrder.XYZ);
 

重点放在旋转的作用上,而不是其基础表示。一旦构建完成,无论其内部表示如何,旋转都是一个操作器,基本上将三维向量转换为其他三维向量。根据应用程序,这些向量的含义可能会有所不同,旋转的语义也会有所不同。

例如,在一个航天器姿态模拟工具中,用户通常会认为向量是固定的(例如地球方向),而框架会发生变化。旋转将向量在惯性框架中的坐标转换为卫星框架中相同向量的坐标。在这种情况下,旋转隐含地定义了两个框架之间的关系。

另一个例子可能是望远镜控制应用程序,其中旋转将静止时的瞄准方向转换为当望远镜指向感兴趣的对象时所需的观测方向。在这种情况下,旋转将静止时的方向在地心框架中转换为相同地心框架中的瞄准方向。这意味着在这种情况下,框架是固定的,而向量在移动。

在许多情况下,这两种方法会结合在一起。在我们的望远镜示例中,我们可能还需要将地心框架中的观测方向转换为惯性框架中的观测方向,考虑到天文台位置和地球旋转,这本质上是第一种方法的应用。

这些示例表明,旋转是用户希望它成为的样子。该类不会将用户引向特定的定义,因此不提供像projectVectorIntoDestinationFramecomputeTransformedDirection这样的方法。它提供更简单和更通用的方法:applyTo(Vector3D)applyInverseTo(Vector3D)

由于旋转基本上是一个矢量运算符,因此可以将多个旋转组合在一起,复合操作r = r1 o r2(这意味着对于每个向量ur(u) = r1(r2(u)))也是一个旋转。因此,我们可以认为除了向量之外,旋转也可以应用于其他旋转(或自身)。根据我们之前的符号,我们会说我们可以将r1应用于r2,而我们得到的结果是r = r1 o r2。为此,该类提供了方法:applyTo(Rotation)applyInverseTo(Rotation)

旋转保证是不可变对象。

另请参阅:
  • 字段详细资料

    • IDENTITY

      public static final Rotation IDENTITY
      单位旋转。
  • 构造器详细资料

    • Rotation

      public Rotation(double q0, double q1, double q2, double q3, boolean needsNormalization)
      从四元数坐标构建旋转。

      可以从一个归一化四元数构建旋转,即一个满足q02 + q12 + q22 + q32 = 1的四元数。如果四元数未归一化,则构造函数可以在预处理步骤中对其进行归一化。

      请注意,一些约定将四元数的标量部分放在第4个分量,矢量部分放在前三个分量。这不是我们的约定。我们将标量部分放在第一个分量。

      参数:
      q0 - 四元数的标量部分
      q1 - 四元数的矢量部分的第一个坐标
      q2 - 四元数的矢量部分的第二个坐标
      q3 - 四元数的矢量部分的第三个坐标
      needsNormalization - 如果为true,则认为坐标未归一化,在使用之前执行归一化预处理步骤
    • Rotation

      public Rotation(Vector3D axis, double angle, RotationConvention convention) throws MathIllegalArgumentException
      从轴和角度构建旋转。
      参数:
      axis - 绕其旋转的轴
      angle - 旋转角度
      convention - 用于角度语义的约定
      抛出:
      MathIllegalArgumentException - 如果轴的范数为零
    • Rotation

      public Rotation(double[][] m, double threshold) throws MathIllegalArgumentException
      从3X3矩阵构建旋转。

      旋转矩阵是正交矩阵,即单位矩阵(其满足m.mT = I的矩阵)具有实系数。单位矩阵的行列式模为1,在正交3X3矩阵中,只有行列式为正(+1)的矩阵是旋转矩阵。

      当一个旋转由一个具有截断值的矩阵定义时(通常当它从技术说明中提取时,只有四到五个有效数字可用),该矩阵不再是正交的。此构造函数通过使用给定矩阵的副本并对副本应用校正来完善其正交性来透明地处理此情况。如果所需校正的Frobenius范数超过给定阈值,则认为该矩阵离真实旋转矩阵太远,并抛出异常。

      参数:
      m - 旋转矩阵
      threshold - 迭代正交性校正的收敛阈值(当校正的Frobenius范数两个步骤之间的差小于此阈值时达到收敛)
      抛出:
      MathIllegalArgumentException - 如果矩阵不是3X3矩阵,或者无法使用给定阈值将其转换为正交矩阵,或者结果正交矩阵的行列式为负
    • Rotation

      public Rotation(Vector3D u1, Vector3D u2, Vector3D v1, Vector3D v2) throws MathRuntimeException
      构建将一对向量转换为另一对向量的旋转。

      除了可能的比例因子外,如果该实例应用于一对(u1, u2),它将产生一对(v1, v2)。

      如果u1和u2之间的角度分离与v1和v2之间的角度分离不同,则将使用校正后的v'2而不是v2,校正后的向量将位于(±v1,+v2)半平面。

      参数:
      u1 - 原始向量对的第一个向量
      u2 - 原始向量对的第二个向量
      v1 - 旋转后u1的期望图像
      v2 - 旋转后u2的期望图像
      抛出:
      MathRuntimeException - 如果一个向量的范数为零,或者一对向量是退化的(即一对向量共线)
    • Rotation

      public Rotation(Vector3D u, Vector3D v) throws MathRuntimeException
      构建将一个向量转换为另一个向量的旋转之一。

      除了可能的比例因子外,如果该实例应用于向量u,它将产生向量v。有无限多个这样的旋转,此构造函数选择与最小关联角度的旋转(即轴与(u,v)平面正交的旋转)。如果u和v共线,则选择任意旋转轴。

      参数:
      u - 原始向量
      v - 旋转后u的期望图像
      抛出:
      MathRuntimeException - 如果一个向量的范数为零
    • Rotation

      public Rotation(RotationOrder order, RotationConvention convention, double alpha1, double alpha2, double alpha3)
      从三个Cardan或Euler基本旋转构建旋转。

      Cardan旋转是绕规范轴X、Y和Z的三次连续旋转,每个轴只使用一次。有6组这样的旋转(XYZ、XZY、YXZ、YZX、ZXY和ZYX)。Euler旋转是绕规范轴X、Y和Z的三次连续旋转,第一次和最后一次旋转是围绕同一轴进行的。有6组这样的旋转(XYX、XZX、YXY、YZY、ZXZ和ZYZ),最流行的是ZXZ。

      请注意,许多人通常将Euler角的术语用于实际上是Cardan角的情况(这种混淆在航空航天业特别普遍,其中横滚、俯仰和偏航角经常错误地标记为Euler角)。

      参数:
      order - 要组合的旋转顺序,从左到右(即我们将使用r1.compose(r2.compose(r3, convention), convention)
      convention - 角度语义使用的约定
      alpha1 - 第一个基本旋转的角度
      alpha2 - 第二个基本旋转的角度
      alpha3 - 第三个基本旋转的角度
  • 方法详细资料

    • revert

      public Rotation revert()
      反转旋转。构建一个反转另一个旋转效果的旋转。这意味着如果r(u) = v,则r.revert(v) = u。实例不会改变。
      返回:
      一个新的旋转,其效果与实例的效果相反
    • getQ0

      public double getQ0()
      获取四元数的标量坐标。
      返回:
      四元数的标量坐标
    • getQ1

      public double getQ1()
      获取四元数的矢量部分的第一个坐标。
      返回:
      四元数的矢量部分的第一个坐标
    • getQ2

      public double getQ2()
      获取四元数的矢量部分的第二个坐标。
      返回:
      四元数的矢量部分的第二个坐标
    • getQ3

      public double getQ3()
      获取四元数的矢量部分的第三个坐标。
      返回:
      四元数的矢量部分的第三个坐标
    • getAxis

      public Vector3D getAxis(RotationConvention convention)
      获取旋转的归一化轴。

      请注意,由于getAngle()始终返回0到π之间的角度,更改约定会更改轴的方向,而不是角度的符号。

      参数:
      convention - 角度语义使用的约定
      返回:
      旋转的归一化轴
      另请参阅:
    • getAngle

      public double getAngle()
      获取旋转的角度。
      返回:
      旋转的角度(在0到π之间)
      另请参阅:
    • getAngles

      public double[] getAngles(RotationOrder order, RotationConvention convention) throws MathIllegalStateException
      获取与实例对应的Cardan或Euler角。

      方程表明每个旋转可以由Cardan或Euler角集的两个不同值定义。例如,如果使用Cardan角,由角度a1、a2和a3定义的旋转与由角度π + a1、π - a2和π + a3定义的旋转相同。此方法实现以下任意选择:

      • 对于Cardan角,所选集是第二个角度在-π/2到π/2之间(即其余弦为正)的集合,
      • 对于Euler角,所选集是第二个角度在0到π之间(即其正弦为正)的集合。

      Cardan和Euler角有一个非常令人失望的缺点:它们都有奇点。这意味着如果实例太接近给定旋转顺序对应的奇点,将无法检索角度。对于Cardan角,这通常称为万向节锁定。无法防止这种情况发生,这是Cardan和Euler表示的固有问题(但不是旋转本身的问题,旋转本身是完全定义的)。对于Cardan角,当第二个角度接近-π/2或+π/2时会出现奇点,对于Euler角,当第二个角度接近0或π时会出现奇点,这意味着对于Euler角,单位旋转始终对应奇点!

      参数:
      order - 要使用的旋转顺序
      convention - 角度语义使用的约定
      返回:
      三个角度的数组,按照指定的顺序
      抛出:
      MathIllegalStateException - 如果旋转对指定的角度集是奇异的
    • getMatrix

      public double[][] getMatrix()
      获取与实例对应的3X3矩阵
      返回:
      与实例对应的矩阵
    • applyTo

      public Vector3D applyTo(Vector3D u)
      将旋转应用于向量。
      参数:
      u - 要应用旋转的向量
      返回:
      一个新的向量,是旋转后u的图像
    • applyTo

      public void applyTo(double[] in, double[] out)
      将旋转应用于存储在数组中的向量。
      参数:
      in - 一个包含三个项目的数组,存储要旋转的向量
      out - 一个包含三个项目的数组,用于放置结果(可以是与in相同的数组)
    • applyInverseTo

      public Vector3D applyInverseTo(Vector3D u)
      将旋转的逆应用于向量。
      参数:
      u - 要应用旋转的逆的向量
      返回:
      一个新的向量,使得u是旋转的图像
    • applyInverseTo

      public void applyInverseTo(double[] in, double[] out)
      将旋转的逆应用于存储在数组中的向量。
      参数:
      in - 一个包含三个项目的数组,存储要旋转的向量
      out - 一个包含三个项目的数组,用于放置结果(可以是与in相同的数组)
    • applyTo

      public Rotation applyTo(Rotation r)
      将实例应用于另一个旋转。

      调用此方法等效于调用compose(r, RotationConvention.VECTOR_OPERATOR)

      参数:
      r - 要应用旋转的旋转
      返回:
      一个新的旋转,是实例与r的组合
    • compose

      public Rotation compose(Rotation r, RotationConvention convention)
      与另一个旋转实例进行组合。

      如果旋转组合的语义对应于矢量运算符约定,将实例应用于旋转是按照以下规则计算组合的顺序:设u为任意矢量,vr1作用于u的图像(即r1.applyTo(u) = v)。设w为旋转r2作用于v的图像(即r2.applyTo(v) = w)。那么w = comp.applyTo(u),其中comp = r2.compose(r1, RotationConvention.VECTOR_OPERATOR)

      如果旋转组合的语义对应于框架变换约定,应用顺序将被颠倒。因此,保持所有r1r2uvwcomp的确切含义与上述相同,comp也可以计算为comp = r1.compose(r2, RotationConvention.FRAME_TRANSFORM)

      参数:
      r - 要应用旋转的旋转
      convention - 用于角度语义的约定
      返回:
      一个新的旋转,是r与实例的组合
    • applyInverseTo

      public Rotation applyInverseTo(Rotation r)
      将实例的逆应用于另一个旋转。

      调用此方法等效于调用composeInverse(r, RotationConvention.VECTOR_OPERATOR)

      参数:
      r - 要应用旋转的旋转
      返回:
      一个新的旋转,是r与实例的逆的组合
    • composeInverse

      public Rotation composeInverse(Rotation r, RotationConvention convention)
      将实例的逆与另一个旋转组合。

      如果旋转组合的语义对应于矢量运算符约定,将实例的逆应用于旋转是按照以下规则计算组合的顺序:设u为任意矢量,vr1作用于u的图像(即r1.applyTo(u) = v)。设wv的逆图像,通过r2(即r2.applyInverseTo(v) = w)。那么w = comp.applyTo(u),其中comp = r2.composeInverse(r1)

      如果旋转组合的语义对应于框架变换约定,应用顺序将被颠倒,这意味着将反转最内部的旋转。因此,保持所有r1r2uvwcomp的确切含义与上述相同,comp也可以计算为comp = r1.revert().composeInverse(r2.revert(), RotationConvention.FRAME_TRANSFORM)

      参数:
      r - 要应用旋转的旋转
      convention - 用于角度语义的约定
      返回:
      一个新的旋转,是r与实例的逆的组合
    • distance

      public static double distance(Rotation r1, Rotation r2)
      计算两个旋转之间的距离

      这里的距离是一种检查两个旋转是否几乎相似(即它们以相同方式转换矢量)或非常不同的方法。在数学上,它被定义为前置到其中一个旋转的旋转r的角度:\(r_1(r) = r_2\)

      这个距离是介于0和π之间的角度。它的值是r1(v)和r2(v)之间的所有可能矢量v的弧度角的最小可能上界。对于某些v,这个上界是达到的。如果两个旋转完全相同,则距离等于0。

      比较两个旋转应该始终使用这个值,而不是例如比较四元数的分量。它更加稳定,并且具有几何意义。此外,比较四元数分量是容易出错的,因为例如四元数(0.36, 0.48, -0.48, -0.64)和(-0.36, -0.48, 0.48, 0.64)表示完全相同的旋转,尽管它们的分量不同(它们是完全相反的)。

      参数:
      r1 - 第一个旋转
      r2 - 第二个旋转
      返回:
      r1和r2之间的距离