Search code examples
three.jscoordinate-transformation

three.js object translate and rotate based on object self coordinate system or world coordinate system


I create a cube in three.js and if i rotate it first then translateX,the cube position is not (10,0,0)

geometry = new THREE.BoxGeometry( 3, 3, 3 );
material = new THREE.MeshBasicMaterial( { color: 0xff0000} );
mesh = new THREE.Mesh( geometry, material );
mesh.position.set(0, 0 , 0);
mesh.rotation.y = Math.PI/4;
mesh.translateX(10);
scene.add( mesh );

picture

but if i translateX it first then rotate,the position is (10,0,0).

So i notice that object translate based on self coordinate system. When i rotate first, the object self coordinate system has chenged. But if i rotate it first then translateX,the cube position is (5.3, 0, -5.3), and rotate it now , it looks like rotation not based on self coordinate system.

png

So i want to know is object translate and rotate based on self coordinate system or world coordinate system.


Solution

  • A concatenation of 2 matrices (matrix multiplication) is not commutative:

    Note, the translation matrix looks like this:

    Matrix4x4 translate;
    
    translate[0] : ( 1,  0,  0,  0 )
    translate[1] : ( 0,  1,  0,  0 )
    translate[2] : ( 0,  0,  1,  0 )
    translate[3] : ( tx, ty, tz, 1 )
    

    And the rotation matrix around Y-Axis looks like this:

    Matrix4x4  rotate;
    float      angle;
    
    rotate[0] : ( cos(angle),  0, sin(angle), 0 )
    rotate[1] : ( 0,           1, 0,          0 )
    rotate[2] : ( -sin(angle), 0, cos(angle), 0 )
    rotate[3] : ( 0,           0, 0,          1 ) 
    

    A matrix multiplication works like this:

    Matrix4x4 A, B, C;
    
    // C = A * B
    for ( int k = 0; k < 4; ++ k )
        for ( int l = 0; l < 4; ++ l )
            C[k][l] = A[0][l] * B[k][0] + A[1][l] * B[k][1] + A[2][l] * B[k][2] +  A[3][l] * B[k][3];
    


    The result of translate * rotate is this:

    model[0] : ( cos(angle),  0,  sin(angle), 0 )
    model[1] : ( 0,           1,  0,          0 )
    model[2] : ( -sin(angle), 0,  cos(angle), 0 )
    model[3] : ( tx,          ty, tz,         1 )
    

    enter image description here


    Note, the result of rotate * translate would be:

    model[0] : ( cos(angle),                     0,   sin(angle),                     0 )
    model[1] : ( 0,                              1,   0,                              0 )
    model[2] : ( -sin(angle),                    0,   cos(angle),                     0 )
    model[3] : ( cos(angle)*tx - sin(angle)*tx,  ty,  sin(angle)*tz + cos(angle)*tz,  1 )
    

    enter image description here