【问题标题】:simd_quatF to euler anglesimd_quatF 到欧拉角
【发布时间】:2021-06-28 12:15:30
【问题描述】:

我正在尝试将我的 quats 转换为 euler,但是在 x/y/z 分量中,只有我的 X 具有准确的值并且 y/z 不正确:- (any1 可以看看/帮助吗?

func quatToEulerAngles(_ quat: simd_quatf) -> SIMD3<Double>{
    
    
    var angles = SIMD3<Double>();
    let qfloat = quat.vector
    let q = SIMD4<Double>(Double(qfloat.x),Double(qfloat.y),Double(qfloat.z), Double(qfloat.w))
    // roll (x-axis rotation)
    
    let sinr_cosp : Double = 2.0 * (q.w * q.x + q.y * q.z);
    let cosr_cosp : Double = 1.0 - 2.0 * (q.x * q.x + q.y * q.y);
    angles.x = atan2(sinr_cosp, cosr_cosp);
    
    // pitch (y-axis rotation)
    let sinp : Double = 2 * (q.w * q.y - q.z * q.x);
    if (abs(sinp) >= 1){
        angles.y = copysign(Double.pi / 2, sinp); // use 90 degrees if out of range
    }
    else{
        angles.y = asin(sinp);
    }
    // yaw (z-axis rotation)
    let siny_cosp : Double = 2 * (q.w * q.z + q.x * q.y);
    let cosy_cosp : Double = 1 - 2 * (q.y * q.y + q.z * q.z);
    angles.z = atan2(siny_cosp, cosy_cosp);
    
    return angles;
}

Wiki 示例转换为 swift。 TIA

【问题讨论】:

    标签: swift quaternions euler-angles


    【解决方案1】:

    我的解决方案是让 (SceneKit) 库来做:

    func quatToEulerAngles(_ quat: simd_quatf) -> SIMD3<Float>{
        let n = SCNNode()
        n.simdOrientation = quat
        return n.simdEulerAngles
    }
    

    【讨论】:

      【解决方案2】:

      我看了看,转成 Swift,

      https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/

      它对我有用。

      func quatToEulerAngles(_ quat: simd_quatf) -> SIMD3<Float>{
      
      var angles = SIMD3<Float>();
      let qfloat = quat.vector
      
      // heading = x, attitude = y, bank = z
      
      let test = qfloat.x*qfloat.y + qfloat.z*qfloat.w;
      
      if (test > 0.499) { // singularity at north pole
          
          angles.x = 2 * atan2(qfloat.x,qfloat.w)
          angles.y = (.pi / 2)
          angles.z = 0
          return  angles
      }
      if (test < -0.499) { // singularity at south pole
          angles.x = -2 * atan2(qfloat.x,qfloat.w)
          angles.y = -(.pi / 2)
          angles.z = 0
          return angles
      }
      
      
      let sqx = qfloat.x*qfloat.x;
      let sqy = qfloat.y*qfloat.y;
      let sqz = qfloat.z*qfloat.z;
      angles.x = atan2(2*qfloat.y*qfloat.w-2*qfloat.x*qfloat.z , 1 - 2*sqy - 2*sqz)
      angles.y = asin(2*test)
      angles.z = atan2(2*qfloat.x*qfloat.w-2*qfloat.y*qfloat.z , 1 - 2*sqx - 2*sqz)
      
      return angles
      

      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-06-21
        • 2019-10-27
        • 1970-01-01
        • 1970-01-01
        • 2013-08-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多