Distortion when the object rotates/revolves

Hi all,
I am very new to three.js and I have been stuck with a problem, for a few days now.
I am trying to rotate an object using rotateOnAxis, it works very well when the axis is (1,0,0) or (0,1,0).
But, whenever I try to change it to maybe (2,0,0) / (1,1,0) , the object starts getting distorted. I am unable to figure out why this is happening, I do expect to see a little distortion if the object is tilted over (1,1,0) but why does it keep growing weirdly and fills the entire screen, and why does distortion also happen for axis (2,0,0), isn’t it also simple rotation around the x-axis? Has it got something to do with normalizing the values?

// three.js info box follows shape

import * as THREE from 'three';
import { OrbitControls } from 'https://unpkg.com/three@0.151.3/examples/jsm/controls/OrbitControls.js';



const renderer = new THREE.WebGLRenderer();


var sunTexture = './img/sun.jpg';
var earthTexture  = './img/earth.jpg';


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

document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
);

const orbit = new OrbitControls(camera, renderer.domElement);

camera.position.set(-90, 140, 140);
orbit.update();

const ambientLight = new THREE.AmbientLight(0x333333);
scene.add(ambientLight);



const textureLoader = new THREE.TextureLoader();

const sunGeo = new THREE.SphereGeometry(16, 30, 30);
const sunMat = new THREE.MeshBasicMaterial({
    map: textureLoader.load(sunTexture)
});
const sun = new THREE.Mesh(sunGeo, sunMat);
scene.add(sun);

function createPlanete(size, texture, position, ring) {
  const geo = new THREE.SphereGeometry(size, 30, 30);
  const mat = new THREE.MeshStandardMaterial({
      map: textureLoader.load(texture)
  });
  const mesh = new THREE.Mesh(geo, mat);
  const obj = new THREE.Object3D();
  obj.add(mesh);
  if(ring) {
      const ringGeo = new THREE.RingGeometry(
          ring.innerRadius,
          ring.outerRadius,
          32);
      const ringMat = new THREE.MeshBasicMaterial({
          map: textureLoader.load(ring.texture),
          side: THREE.DoubleSide
      });
      const ringMesh = new THREE.Mesh(ringGeo, ringMat);
      obj.add(ringMesh);
      ringMesh.position.x = position;
      ringMesh.rotation.x = -0.5 * Math.PI;
  }
  scene.add(obj);
  mesh.position.x = position;
  return {mesh, obj}
}



const earth = createPlanete(6,earthTexture,62);



const pointLight = new THREE.PointLight(0xFFFFFF, 2, 300);
scene.add(pointLight);
var first_vector = new THREE.Vector3(3,2,0);
var second_vector = new THREE.Vector3(2,1,0);
const points = [];
points.push( new THREE.Vector3(0, 0, 0 ) );
points.push( new THREE.Vector3( 0.5, 0.5, 0 ) );
// points.push( new THREE.Vector3( 100, 0, 0 ) );
const geometry = new THREE.BufferGeometry().setFromPoints( points );
const material = new THREE.LineBasicMaterial( { color: 0x0000ff } );
const line = new THREE.Line( geometry, material );
scene.add(line)
renderer.render(scene,camera);
// var vector_axis = first_vector.addVectors(first_vector,second_vector);
var vector_axis = new THREE.Vector3(2,0,0);

function animate() {
    //Self-rotation
    
    // earth.mesh.rotateY(0.02);
    earth.mesh.rotateOnAxis(vector_axis,Math.PI/180);
   

    //Around-sun-rotation
    
    // earth.obj.rotateY(0.01);
    

    renderer.render(scene, camera);
}

renderer.setAnimationLoop(animate);

window.addEventListener('resize', function() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
});

Please help me with this, as I am not finding any discussion related to this and I need to understand this

The rotation axis must be normalized vector, i.e. its length must be 1. So:

  • (1,0,0) – is good vector
  • (0,1,0) – is good vector
  • (1,1,0) – is NOT a good vector, as its length is 1.41…
  • (2,0,0) – is NOT a good vector, as its length is 2

You can use .normalize to set the length to 1 prior to rotation. Alternatively, you can use .setLength(1).

2 Likes

It works, thanks a lot :slight_smile:

1 Like