【问题标题】:Default Object.rotation's axis of rotation (Three.js)默认 Object.rotation 的旋转轴(Three.js)
【发布时间】:2018-05-30 02:58:35
【问题描述】:

更改对象的旋转属性值是否会围绕世界轴或对象的轴旋转对象?例如

object.rotation.x += 2

这会围绕世界 X 轴或对象的 X 轴旋转对象吗? 我尝试了以下示例:

var materials = []; 
materials.push( [ new THREE.MeshBasicMaterial( { color: 0xff0000 } ) ] );
materials.push( [ new THREE.MeshBasicMaterial( { color: 0xff0000 } ) ] );
materials.push( [ new THREE.MeshBasicMaterial( { color: 0x00ff00 } ) ] );
materials.push( [ new THREE.MeshBasicMaterial( { color: 0x00ff00 } ) ] );
materials.push( [ new THREE.MeshBasicMaterial( { color: 0x0000ff } ) ] );
materials.push( [ new THREE.MeshBasicMaterial( { color: 0x0000ff } ) ] );

object = new THREE.Mesh( new THREE.CubeGeometry( 20, 20, 20, 1, 1, 1, materials ), new THREE.MeshFaceMaterial() );

object.position.x = 0;
object.position.y = 0;
object.position.z = 0;

object.rotation.x = 0;
object.rotation.y = 0;
object.rotation.z = 0;

object.scale.x = 1;
object.scale.y = 1;
object.scale.z = 1;

scene.add( object );

After i have added the object to the scene i tried the following - 
object.rotation.x += Math.PI/4;
object.rotation.y += Math.PI/4;
object.rotation.z += Math.PI/4;

到现在为止,对象相对于它自己的 X、Y 和 Z 轴旋转。 但这样做:

object.rotation.x += Math.Pi/4;

现在将对象围绕世界 X 轴而不是对象的 X 轴旋转 45 度。

【问题讨论】:

    标签: three.js


    【解决方案1】:

    旋转在本地空间中。但是,它们会按照您可以自行设置的特定顺序进行评估。 object.rotation 属性是一个Euler,正如您在order-property 的描述中看到的那样:

    应用旋转的顺序。默认为“XYZ”,这意味着 对象将首先围绕其 X 轴旋转,然后围绕其 Y 轴旋转 轴,最后是 Z 轴。其他可能性是:'YZX'、'ZXY'、 “XZY”、“YXZ”和“ZYX”。这些必须是大写的。 Three.js 使用固有的 Tait-Bryan 角。这意味着旋转 是相对于局部坐标系执行的。那是, 对于订单 'XYZ',旋转首先围绕局部 X 轴(其中 与世界 X 轴相同),然后围绕本地 Y(现在可能 不同于世界 Y 轴),然后是本地 Z(可能是 不同于世界 Z 轴)。

    (我添加的重点)。

    考虑以下示例,每个立方体都使用相同的 y 轴旋转进行更新。在每种情况下,旋转都在局部空间中围绕 y 轴发生,但是:

    • 第一个立方体没有在任何其他轴上旋转,使其 局部空间轴与世界空间轴相同。
    • 第二个立方体已绕其 x 轴旋转,这意味着 y 轴也会旋转。
    • 第三个立方体也被旋转了,但是旋转的顺序是 更改为首先发生 y 轴旋转,而它仍然与世界 y 轴相同,然后围绕 x 旋转。

    const canvas = document.getElementById("canvas");
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(10, 2, 20, 40);
    const renderer = new THREE.WebGLRenderer({ canvas });
    const light = new THREE.PointLight();
    light.position.set(0, 5, 10)
    scene.add(light);
    camera.position.set(0, 0, 25);
    
    const material = new THREE.MeshLambertMaterial();
    const geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
    const cube1 = new THREE.Mesh(geometry, material);
    const cube2 = new THREE.Mesh(geometry, material);
    const cube3 = new THREE.Mesh(geometry, material);
    cube1.position.set(-2, 0, 0);
    cube2.position.set( 0, 0, 0);
    cube3.position.set( 2, 0, 0);
    scene.add(cube1);
    scene.add(cube2);
    scene.add(cube3);
    
    //The first cube is not rotated
    cube1.rotation.set(0, 0, 0);
    //The second cube is rotated pi/4 rad around X
    cube2.rotation.set(Math.PI/4, 0, 0);
    //The third cube is rotated pi/4 rad around X
    //AND the rotation order is set to YXZ to make the y-rotation happen first
    cube3.rotation.set(Math.PI/4, 0, 0);
    cube3.rotation.order = "YXZ";
    
    let t0 = performance.now();
    function update(){
    	const t1 = performance.now();
    	const rotation = 0.001 * (t1 - t0);
      
      cube1.rotation.y += rotation;
      cube2.rotation.y += rotation;
      cube3.rotation.y += rotation;
      
      renderer.render(scene, camera);
    
    	t0 = t1;
      requestAnimationFrame(update);
    }
    
    update();
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.js"></script>
    <canvas id="canvas" width="400" height="200"></canvas>

    【讨论】:

    • 旋转对象看起来像object.rotation = Euler {_x: 0, _y: 0, _z: 0, _order: "XYZ", onChangeCallback: ƒ}。即使我这样做 object.rotation.set(0, 0, Math.PI / 2)object.rotation =Euler {_x: 0, _y: 0, _z: 1.5707963267948966, _order: "XYZ", onChangeCallback: ƒ} 对象在世界 Z 轴上旋转
    • 好吧,如果您执行object.rotation.set(0,0,z),您会将 x 和 y 值重置为 0。您可以像 object.rotation.z += Math.Pi/4; 在问题中所做的那样进行旋转,请注意它们在order设置的具体顺序。
    • 我已经尝试了所有可能的顺序'YZX','ZXY','XZY','YXZ'和'ZYX',a.rotation.order = "ORDER",之后我做了object.rotation.z += Math.PI/4,对象在旋转仅在世界 Z 轴上。
    • @sarthaksaxena 我已经添加了一个示例,希望可以澄清一下。
    • 非常感谢,明白我的代码有什么问题了。
    猜你喜欢
    • 1970-01-01
    • 2013-08-06
    • 2015-06-15
    • 2012-07-23
    • 2017-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    相关资源
    最近更新 更多