Search code examples
javascriptthree.jsrotatetransform

Rotate object around arbitrary axis in Three.js,just like the moon around the Earth.


I have tried many solutions of the question,but the object
still around his own axis without any translate.


Solution

  • You might want to add the object as the child of another object, and rotate that object instead...

    var renderer = new THREE.WebGLRenderer();
    var w = 300;
    var h = 200;
    renderer.setSize( w,h );
    document.body.appendChild( renderer.domElement );
    
    var scene = new THREE.Scene();
      	var camera = new THREE.PerspectiveCamera(
    	45,		// Field of view
    	w/h,	// Aspect ratio
    	0.1,		// Near
    	10000		// Far
    );
    camera.position.set( 15, 10, 15 );
    camera.lookAt( scene.position );
    controls = new THREE.OrbitControls(camera, renderer.domElement);
    
    var light = new THREE.PointLight( 0x808080 );
    light.position.set( 20, 20, 20 );
    scene.add( light );
    var light1 = new THREE.AmbientLight( 0x101010 );
    light1.position.set( 20, 20, 20 );
    scene.add( light1 );
    var light2 = new THREE.PointLight( 0x808080 );
    light2.position.set( -20, 20, -20 );
    scene.add( light2 );
    var light3 = new THREE.PointLight( 0x808080 );
    light3.position.set( -20, -20, -20 );
    scene.add( light3 );
    var mkBody=(rad,color)=>{   
    var sphereGeom = new THREE.SphereGeometry(rad,16,16);
    var material = new THREE.MeshLambertMaterial( { color: color } );
    var mesh = new THREE.Mesh( sphereGeom, material );
    return mesh;
    }
    var sun = mkBody(2,0xffee00)
    scene.add( sun )
    sun.material.emissive.set(0x808000)
    var b1 = mkBody(0.7,0x80ffff)
    b1.position.set(6,0,0)
    sun.add( b1 )
    var b2 = mkBody(0.2,0xeeeeee)
    b2.position.set(1.1,0,0)
    b1.add( b2 )
    sun.onBeforeRender = function(){
        this.rotation.y+=0.01
    }
    b1.onBeforeRender = function(){
        this.rotation.y+=0.1
    }
    renderer.setClearColor( 0x404040, 1);
    
    (function animate() {
        requestAnimationFrame(animate);
        controls.update();
        renderer.render(scene, camera);
    })();
    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

    Another option is to transform the geometry itself...

    var renderer = new THREE.WebGLRenderer();
    var w = 300;
    var h = 200;
    renderer.setSize( w,h );
    document.body.appendChild( renderer.domElement );
    
    var scene = new THREE.Scene();
      	var camera = new THREE.PerspectiveCamera(
    	45,		// Field of view
    	w/h,	// Aspect ratio
    	0.1,		// Near
    	10000		// Far
    );
    camera.position.set( 15, 10, 15 );
    camera.lookAt( scene.position );
    controls = new THREE.OrbitControls(camera, renderer.domElement);
    
    var light = new THREE.PointLight( 0x808080 );
    light.position.set( 20, 20, 20 );
    scene.add( light );
    var light1 = new THREE.AmbientLight( 0x101010 );
    light1.position.set( 20, 20, 20 );
    scene.add( light1 );
    var light2 = new THREE.PointLight( 0x808080 );
    light2.position.set( -20, 20, -20 );
    scene.add( light2 );
    var light3 = new THREE.PointLight( 0x808080 );
    light3.position.set( -20, -20, -20 );
    scene.add( light3 );
    var mkBody=(rad,color)=>{   
        var sphereGeom = new THREE.SphereGeometry(rad,16,16);
        var material = new THREE.MeshLambertMaterial( { color: color } );
        var mesh = new THREE.Mesh( sphereGeom, material );
        return mesh;
    }
    var sun = mkBody(2,0xffee00)
    scene.add( sun )
    sun.material.emissive.set(0x808000)
    var b1 = mkBody(0.7,0x80ffff)
    b1.position.set(6,0,0)
    sun.add( b1 )
    b1.updateMatrixWorld();
    b1.geometry.applyMatrix(b1.matrixWorld); //Transform the actual geometry...
    scene.add(b1); //Now reparent it to the scene
    b1.position.set(0,0,0); //And reset its position...
    
    sun.onBeforeRender = function(){
        this.rotation.y+=0.01
    }
    b1.onBeforeRender = function(){
        this.rotation.y+=0.1
    }
    renderer.setClearColor( 0x404040, 1);
    
    (function animate() {
        requestAnimationFrame(animate);
        controls.update();
        renderer.render(scene, camera);
    })();
    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>