# How to gradually rotate a cube to face another cube that are both on a flat plane surface

**URL:** <https://discourse.threejs.org/t/how-to-gradually-rotate-a-cube-to-face-another-cube-that-are-both-on-a-flat-plane-surface/27374>\
**Category:** Questions\
**Tags:** transform\
**Created:** [June 19, 2021, 9:24pm UTC](https://discourse.threejs.org/t/how-to-gradually-rotate-a-cube-to-face-another-cube-that-are-both-on-a-flat-plane-surface/27374 "2021-06-19T21:24:34Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![frankfnople](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@frankfnople](https://discourse.threejs.org/u/frankfnople)\
**Post date:** [June 19, 2021, 9:24pm UTC](https://discourse.threejs.org/t/how-to-gradually-rotate-a-cube-to-face-another-cube-that-are-both-on-a-flat-plane-surface/27374/1 "2021-06-19T21:24:34Z")

</div>

Hi.

I have two cubes on a plane surface (which is their ground). I would like to gradually rotate cube 1 to face towards cube 2 and then move cube 1 towards cube 2. As they are both on the ground I figured I just need to rotate cube 1 on the y axis until it faces cube 2.

So far I have looked at rotateY, slerp, rotateTowards, and lookAt.

lookAt turns cube 1 towards cube 2 correctly, but it does it instantly, not gradually.

rotateY works in that it rotates parallel to the ground but I can’t figure out how to stop it when it faces in the direction of cube 2.

slerp and rotateTowards don’t seem to give the right result.

Is there a standard way of doing something like this, and if so, may someone provide an example?

Thank you very much for your time.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [June 20, 2021, 7:59am UTC](https://discourse.threejs.org/t/how-to-gradually-rotate-a-cube-to-face-another-cube-that-are-both-on-a-flat-plane-surface/27374/2 "2021-06-20T07:59:53Z")

</div>

> [@frankfnople](#):
>
> slerp and rotateTowards don’t seem to give the right result.

`Quaternion.rotateTowards()` is the intended method for this use case. Please show how you are using it in your code.

---

<div class="post-metadata">

**Author:** ![frankfnople](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@frankfnople](https://discourse.threejs.org/u/frankfnople)\
**Post date:** [June 20, 2021, 1:46pm UTC](https://discourse.threejs.org/t/how-to-gradually-rotate-a-cube-to-face-another-cube-that-are-both-on-a-flat-plane-surface/27374/3 "2021-06-20T13:46:36Z")

</div>

Thanks for your reply.  
This is the start scene…

![startingscene](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/e/3/e3725ea247f89c569be29117aa4c3e7a88ca9124.jpeg)

If the cube is rotated on the z axis as shown in the code, the rotateTowards will orientate the model as if leaning over but also faces front still.

![rotatetowards](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/1/8/18f65d68ca86363829c49fb047e43f37816cbf83.jpeg)

I would like the model to face the cube by rotating on the y axis to emulate what you would do while standing on the ground. The intended end result should be…

![intendedresult](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/a/b/ab9e0c2583063110a381b49c2e107d025655491d.jpeg)

The model should rotate to face the cube on the y axis regardless of how the cube is tilted.

My code is…

```javascript
import * as THREE from './build/three.module.js';
		import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';

        let scene, renderer, camera;
        let model;
        let cube;

        init();

        function init() {

            const container = document.getElementById('container');

            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
            camera.position.set(0, 1.5, - 7);
            camera.lookAt(0, 0, 0);

            scene = new THREE.Scene();
            scene.background = new THREE.Color(0xa0a0a0);
            scene.fog = new THREE.Fog(0xa0a0a0, 10, 50);

            const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444);
            hemiLight.position.set(0, 20, 0);
            scene.add(hemiLight);

            const dirLight = new THREE.DirectionalLight(0xffffff);
            dirLight.position.set(- 3, 10, - 10);
            dirLight.castShadow = true;
            dirLight.shadow.camera.top = 2;
            dirLight.shadow.camera.bottom = - 2;
            dirLight.shadow.camera.left = - 2;
            dirLight.shadow.camera.right = 2;
            dirLight.shadow.camera.near = 0.1;
            dirLight.shadow.camera.far = 40;
            scene.add(dirLight);

            // ground
            const mesh = new THREE.Mesh(new THREE.PlaneGeometry(100, 100), new THREE.MeshPhongMaterial({ color: 0x999999, depthWrite: false }));
            mesh.rotation.x = - Math.PI / 2;
            mesh.receiveShadow = true;
            scene.add(mesh);

            const loader = new GLTFLoader();
            loader.load('/my-app/src/app/scene-models/Soldier.glb', function (gltf) {

                model = gltf.scene;
                model.position.set(0, 0, 0);
                scene.add(model);

                model.traverse(function (object) {

                    if (object.isMesh) object.castShadow = true;

                });

                animate();

            });

            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.outputEncoding = THREE.sRGBEncoding;
            renderer.shadowMap.enabled = true;
            container.appendChild(renderer.domElement);

            const geometry = new THREE.BoxGeometry(1, 1, 1);
            const material = new THREE.MeshNormalMaterial();
            cube = new THREE.Mesh(geometry, material);
            cube.position.set(3, 0, 0);
            cube.rotateZ(.5);
            scene.add(cube);

            window.addEventListener('resize', onWindowResize);

        }

        function onWindowResize() {

            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();

            renderer.setSize(window.innerWidth, window.innerHeight);

        }

        function animate() {

            requestAnimationFrame(animate);

            if (!model.quaternion.equals(cube.quaternion)) {
                model.quaternion.rotateTowards(cube.quaternion, .01);
            }

            renderer.render(scene, camera);

        }

```

Any further help is greatly appreciated.

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [June 21, 2021, 7:29am UTC](https://discourse.threejs.org/t/how-to-gradually-rotate-a-cube-to-face-another-cube-that-are-both-on-a-flat-plane-surface/27374/4 "2021-06-21T07:29:22Z")

</div>

Try it like so: [https://jsfiddle.net/r6j7yLea/1/](https://jsfiddle.net/r6j7yLea/1/)

Notice that the solider model is no good asset for this use case since when no rotation is applied, it looks along the negative z axis. This is not the default of 3D objects in `three.js` where it is the positive z axis. Hence, the model should be corrected in Blender before using it like in the fiddle.

Apart from that, it is important that the target point and the model’s position lie in the same conceptual y-plane.

---

<div class="post-metadata">

**Author:** ![frankfnople](https://avatars.discourse-cdn.com/v4/letter/f/439d5e/32.png) [@frankfnople](https://discourse.threejs.org/u/frankfnople)\
**Post date:** [June 21, 2021, 10:49am UTC](https://discourse.threejs.org/t/how-to-gradually-rotate-a-cube-to-face-another-cube-that-are-both-on-a-flat-plane-surface/27374/5 "2021-06-21T10:49:59Z")

</div>

Phenomenal!

I have applied this and it works perfectly.

Thank you very much!
