代码之家  ›  专栏  ›  技术社区  ›  Philip Zhu

three.js如何处理非单位四元数的旋转?

  •  0
  • Philip Zhu  · 技术社区  · 3 年前

    使用three.js,我使用四元数旋转箭头(位于单位球体上)。

    我在这个链接中有一个完整的脚本: https://jsfiddle.net/PhilipZhu/937wov02/1/

    大多数代码用于设置。相关零件类型如下:

    // define a quaternion
    
    let u = -0.3; // scaling factor of non-unit quaternion
    let t = 0.25*Math.PI; // rotate by angle 2*t
    
    let w = Math.exp(u)*Math.cos(t);
    let x = Math.exp(u)*Math.sin(t);
    let y = 0;
    let z = 0;
    
    let q = { w: w, x: x, y: y, z: z };
    

    上面的代码设置了一个四元数,该四元数绕x轴旋转 2*t ,并且四元数按比例缩放 exp(u) 。这意味着什么时候 u=0 ,q是单位四元数。

    // define an arrow shape
    const points = [];
    points.push( new THREE.Vector3(  0    , 1 ,  0     ) );
    ...
    points.push( new THREE.Vector3(  0    , 1 ,  0     ) );
    

    这些点追踪位于单位球体上的箭头形状。

    // Method 1: apply quaternion to Vector3 (blue)
    let transformedPoints = points.map((point) => {
      return point.clone().applyQuaternion(quaternion);
    });
    const arrowMaterial1 = new THREE.LineBasicMaterial({color: 0x0000ff});
    const geometry1 = new THREE.BufferGeometry().setFromPoints( transformedPoints );
    const arrow1 = new THREE.Line( geometry1, arrowMaterial1 );
    arrow1.position.set(0, 0, 0);
    scene.add(arrow1);
    
    // Method 2: apply quaternion to Object3 (green)
    const arrowMaterial2 = new THREE.LineBasicMaterial({color: 0x00ff00});
    const geometry2 = new THREE.BufferGeometry().setFromPoints( points );
    const arrow2 = new THREE.Line( geometry2, arrowMaterial2 );
    arrow2.position.set(0, 0, 0);
    arrow2.setRotationFromQuaternion(quaternion);
    scene.add(arrow2);
    

    我的主要问题是,当q是非酉时,上面的方法1和方法2给出了不同的形状。

    方法1将几何数据复制到(three.js)Vector3对象,然后将四元数应用到Vector3,该方法给出了直观的结果:按预期角度旋转并相对于原点缩放。

    方法2设置一个(three.js)Object3对象,然后将四元数应用于Ojbect3。这给出了一个非直观的结果,与方法1给出的结果不同。

    背后的原因是什么(如果有的话)?还是因为非单位四元数变换根本不常见,所以这是一个没有人关心的错误?

    0 回复  |  直到 3 年前