【问题标题】:Getting Euler angle from VRPose.orientation Quarternion从 Pose.orientation 四元数中获取欧拉角
【发布时间】:2018-08-25 16:25:18
【问题描述】:

我需要得到手机面向的方向和地平线之间的角度theta(见图)。

为此,我正在使用 web-vr polyfill 库,它允许我访问 VRPose.orientation,将相机的方向作为四元数。

现在,我正在尝试将四元数转换为欧拉角,以便能够获得我需要的 theta 角,但通过我的尝试,该角并不独立于其他旋转角度(即,如果用户从其位置转身,同时保持手机处于相同方向,角度 theta 会发生变化)。

这是我的代码。

  var orientation = frameData.pose.orientation
  var a = orientation[0]
  var b = orientation[1]
  var c = orientation[2]
  var d = orientation[3]

  var yaw, pitch, roll

  roll = Math.atan(2*(a*b + c*d)/(pow2(a) - pow2(b) - pow2(c) + pow2(d)))

  pitch = - Math.asin(2*(b*d - a*c))

  theta = Math.atan(2*(a*d + b*c)/(pow2(a) + pow2(b) - pow2(c) - pow2(d)))

任何想法我做错了什么或其他解决方案的建议?

谢谢

【问题讨论】:

    标签: javascript three.js geometry webvr


    【解决方案1】:

    您可以将四元数应用于单位向量,然后计算角度:

    const vec = new THREE.Vector3();
    
    function getCameraAngle() {
      // Reset the vector to a unit vector pointing into the scene
      vec.set(0, 0, -1);
      // Apply the camera quaternion
      vec.applyQuaternion(camera.quaternion);
      // Calculate the angle based on Y
      return Math.asin(vec.y) * THREE.Math.RAD2DEG;
    }
    
    const angle = document.getElementById('angle');
    
    function animate() {
      angle.textContent = getCameraAngle().toFixed(2);
      renderer.render(scene, camera);
    };
    
    
    // Boilerplate
    new WebVRPolyfill();
    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
    const scene = new THREE.Scene();
    
    const renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.vr.enabled = true;
    document.body.appendChild(renderer.domElement);
    WEBVR.createButton(renderer);
    
    scene.add(new THREE.AmbientLight('white', 1));
    
    let grid = new THREE.GridHelper();
    scene.add(grid);
    grid = new THREE.GridHelper();
    grid.rotation.x = Math.PI / 2;
    grid.position.set(0, 5, -5);
    scene.add(grid);
    grid = new THREE.GridHelper();
    grid.rotation.x = Math.PI / 2;
    grid.position.set(0, 5, 5);
    scene.add(grid);
    grid = new THREE.GridHelper();
    grid.rotation.x = Math.PI / 2;
    grid.rotation.z = Math.PI / 2;
    grid.position.set(5, 5, 0);
    scene.add(grid);
    grid = new THREE.GridHelper();
    grid.rotation.x = Math.PI / 2;
    grid.rotation.z = Math.PI / 2;
    grid.position.set(-5, 5, 0);
    scene.add(grid);
    grid = new THREE.GridHelper();
    grid.position.set(0, 10, 0);
    scene.add(grid);
    
    renderer.setAnimationLoop(animate);
    
    window.addEventListener("resize", () => {
      renderer.setSize(window.innerWidth, window.innerHeight);
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
    });
    body {
      margin: 0;
      font-size: 0;
    }
    
    #angle {
      position: absolute;
      top: 10px;
      left: 10px;
      background: white;
      font-size: 20pt;
      font-family: monospace;
      padding: 0.2em;
    }
    <script src="https://unpkg.com/webvr-polyfill@0.10.6/build/webvr-polyfill.min.js"></script>
    <script src="https://unpkg.com/three@0.95.0/build/three.min.js"></script>
    <script src="https://unpkg.com/three@0.95.0/examples/js/vr/WebVR.js"></script>
    
    <span id="angle"></span>

    【讨论】:

    • 完美。非常非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2012-06-21
    • 2019-10-27
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    相关资源
    最近更新 更多